Compare commits
589 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcfa0287b9 | ||
|
|
681ab1b889 | ||
|
|
46051d5ec8 | ||
|
|
d8d692b8ba | ||
|
|
cc344dfbe3 | ||
|
|
0dec17fc3f | ||
|
|
f12446d3ba | ||
|
|
1c9ccb5e03 | ||
|
|
a463e794ce | ||
|
|
e0ca5eff38 | ||
|
|
1ebb3296ee | ||
|
|
b37f682ee2 | ||
|
|
da905108b4 | ||
|
|
bd57b4f9b5 | ||
|
|
9027dc3252 | ||
|
|
5750cc2e1a | ||
|
|
bbcce9f7b7 | ||
|
|
6bcb4af10f | ||
|
|
8d13234554 | ||
|
|
982f35b424 | ||
|
|
2e170cd15a | ||
|
|
cc6c67d81c | ||
|
|
669fd1fd1d | ||
|
|
8cd7de276e | ||
|
|
3bf3a46cd4 | ||
|
|
8edcc62a8d | ||
|
|
31c45ffc52 | ||
|
|
d8cc8b550b | ||
|
|
dbc7a83e8c | ||
|
|
19c0b70d26 | ||
|
|
9d617777d5 | ||
|
|
5d57deaa4f | ||
|
|
b5955597a4 | ||
|
|
b1410b27b8 | ||
|
|
0e777d386e | ||
|
|
b6d9c30eea | ||
|
|
5160a2eb53 | ||
|
|
40ed227c23 | ||
|
|
2a4400c147 | ||
|
|
82eb630be7 | ||
|
|
4a8db20a9a | ||
|
|
8db9b6a2a6 | ||
|
|
c159501d0d | ||
|
|
76e63d1124 | ||
|
|
79b6684840 | ||
|
|
214fe82c7e | ||
|
|
c489e31f5d | ||
|
|
efd812cb1a | ||
|
|
3a920dc401 | ||
|
|
7cb1598991 | ||
|
|
6a8800286e | ||
|
|
f3f3029014 | ||
|
|
0e52fde047 | ||
|
|
9b3fba04f9 | ||
|
|
1101634f6a | ||
|
|
499b7a6ecf | ||
|
|
cea9b0bc78 | ||
|
|
dea3428804 | ||
|
|
47d600a9b4 | ||
|
|
eae4bafff3 | ||
|
|
9e08bd44fb | ||
|
|
d9883e4442 | ||
|
|
e6f7e556e8 | ||
|
|
4b84e79cc3 | ||
|
|
05ae22a85c | ||
|
|
a0e5c3a2e2 | ||
|
|
712f9eba35 | ||
|
|
803b2f9a93 | ||
|
|
92f980f4b7 | ||
|
|
52e98f1bd9 | ||
|
|
6cd9a328a4 | ||
|
|
03a73667db | ||
|
|
a29d6d8c5b | ||
|
|
2a08969ddc | ||
|
|
3a94b7399b | ||
|
|
41d000c97e | ||
|
|
78da283c1b | ||
|
|
e362843705 | ||
|
|
097b8d4881 | ||
|
|
3b6122f86d | ||
|
|
f75a36945c | ||
|
|
e4c32cdb77 | ||
|
|
fb19abd09a | ||
|
|
d2afc206b2 | ||
|
|
43ff5f93e8 | ||
|
|
5e6a50b2f9 | ||
|
|
23b9533791 | ||
|
|
d1f8cfcfdc | ||
|
|
aa2336be92 | ||
|
|
e64617212e | ||
|
|
85e45cad95 | ||
|
|
9fa512a652 | ||
|
|
349371bbc9 | ||
|
|
4446961167 | ||
|
|
04473ada48 | ||
|
|
1b66b77f69 | ||
|
|
8fc6ea6489 | ||
|
|
eaf2da20a6 | ||
|
|
083c157b05 | ||
|
|
e26e39a7f8 | ||
|
|
04e7ccabea | ||
|
|
415e1d8ea3 | ||
|
|
3bb8852ef7 | ||
|
|
c0fddd9467 | ||
|
|
41c066d4c8 | ||
|
|
2316931e3b | ||
|
|
77f3d55149 | ||
|
|
b319579b78 | ||
|
|
0c0febe28a | ||
|
|
d41736b828 | ||
|
|
c88bbbd6cc | ||
|
|
d88b7cfb08 | ||
|
|
1385fa4190 | ||
|
|
0346a106f8 | ||
|
|
60a4e7e5d4 | ||
|
|
39ab6bd630 | ||
|
|
0518d2785f | ||
|
|
a6b8ec3134 | ||
|
|
6d22387727 | ||
|
|
7221579340 | ||
|
|
ee29ffaf4f | ||
|
|
8935aa6523 | ||
|
|
288481ffe1 | ||
|
|
f961e9912e | ||
|
|
0edf73bf3d | ||
|
|
f5b060a9f1 | ||
|
|
c26a3e481f | ||
|
|
8b3b5d0290 | ||
|
|
37edc66418 | ||
|
|
becd5088df | ||
|
|
e517bef17f | ||
|
|
da2b28a3bb | ||
|
|
965bb6d08a | ||
|
|
049728665f | ||
|
|
fcb9a93d05 | ||
|
|
425eaf8a2a | ||
|
|
47ce996d36 | ||
|
|
e890ae02c2 | ||
|
|
9bc3565af1 | ||
|
|
a0cd5d70ae | ||
|
|
3170dc3e63 | ||
|
|
10ad2edd3c | ||
|
|
c9f22f4e55 | ||
|
|
3047c524d9 | ||
|
|
89e5295421 | ||
|
|
cdabe7fc9e | ||
|
|
b0fe439309 | ||
|
|
6685cd4e21 | ||
|
|
7a683bd02e | ||
|
|
6ed03a83a5 | ||
|
|
182cb800a8 | ||
|
|
2acd1cafd0 | ||
|
|
dd35bfd1a1 | ||
|
|
1f17e71dce | ||
|
|
0954f6b1bb | ||
|
|
6b29bf1c71 | ||
|
|
f6afdf0145 | ||
|
|
412847d6a2 | ||
|
|
5b2786213a | ||
|
|
6ed25c19e6 | ||
|
|
e2c483f856 | ||
|
|
5c5e0cb86d | ||
|
|
b9b84cd963 | ||
|
|
e517bcc2b2 | ||
|
|
7f5a6d479e | ||
|
|
8de09ddf37 | ||
|
|
e08ae8d01d | ||
|
|
a00d719ed2 | ||
|
|
08ca1b00b7 | ||
|
|
7b86f81e29 | ||
|
|
8cd4afeaf1 | ||
|
|
b606b621e5 | ||
|
|
5c2b14b910 | ||
|
|
a19a023f1f | ||
|
|
e6cef75162 | ||
|
|
1371f72cfb | ||
|
|
8ecaa2f057 | ||
|
|
8132174754 | ||
|
|
bcc285095d | ||
|
|
cb369727cd | ||
|
|
9bdbeaba66 | ||
|
|
d85cb77123 | ||
|
|
1bee83ccc4 | ||
|
|
4d1894327e | ||
|
|
1391b3bf47 | ||
|
|
b6d5b82c48 | ||
|
|
9dfb0fe3a9 | ||
|
|
455546975c | ||
|
|
c189aa6a0a | ||
|
|
8442528fa7 | ||
|
|
d09787e150 | ||
|
|
0285a89c7c | ||
|
|
7d7784fecb | ||
|
|
ca6f196001 | ||
|
|
e621cf2bc1 | ||
|
|
906ab5483e | ||
|
|
1549c25709 | ||
|
|
fe1d07e58c | ||
|
|
793a1aa3c8 | ||
|
|
4a94477532 | ||
|
|
9bc2b1949c | ||
|
|
49691ba85e | ||
|
|
87ff0c1bbc | ||
|
|
de30c3f8d6 | ||
|
|
4c3bfb89a4 | ||
|
|
8b21cfe7eb | ||
|
|
46700f7b74 | ||
|
|
014be7e143 | ||
|
|
b3ff2c35ea | ||
|
|
9c786de8f9 | ||
|
|
188e108d7c | ||
|
|
7d7842f2f3 | ||
|
|
901a3715cb | ||
|
|
095b5ce97c | ||
|
|
1d3f70e07f | ||
|
|
5e308da81a | ||
|
|
2231e4068d | ||
|
|
b3680f0016 | ||
|
|
89527796f6 | ||
|
|
165d593fdb | ||
|
|
d8b09628f0 | ||
|
|
d35e8ec351 | ||
|
|
f50b0ce8af | ||
|
|
ed8607b710 | ||
|
|
ea28d3b6f3 | ||
|
|
827cea3245 | ||
|
|
b2a0d83518 | ||
|
|
85e0139f32 | ||
|
|
80d5df0ceb | ||
|
|
3a54e5b644 | ||
|
|
acc6a9bd01 | ||
|
|
96af6dc499 | ||
|
|
675e1b4118 | ||
|
|
8ca484f538 | ||
|
|
9a25f4fbe4 | ||
|
|
467ec46cd3 | ||
|
|
52feff2213 | ||
|
|
add65f2f0c | ||
|
|
20f2bae49b | ||
|
|
8eb9df8447 | ||
|
|
88aaffa957 | ||
|
|
469c0b41df | ||
|
|
4a34f72f22 | ||
|
|
4d721e1410 | ||
|
|
9c91da8a2b | ||
|
|
5b9d942313 | ||
|
|
d6b37cb87e | ||
|
|
9c6f077818 | ||
|
|
0b5d936dbe | ||
|
|
6eebed33b2 | ||
|
|
43085a80bc | ||
|
|
4f90b114ea | ||
|
|
d9fa353a06 | ||
|
|
9a1d7460f6 | ||
|
|
d18d17b861 | ||
|
|
4b57c0d4e6 | ||
|
|
ccd9b2d2c5 | ||
|
|
ec770cd819 | ||
|
|
b7ec633fb2 | ||
|
|
7aabff1236 | ||
|
|
9dc1bdffb1 | ||
|
|
2ac672a663 | ||
|
|
11ae6b29d5 | ||
|
|
f201f59e27 | ||
|
|
25d45e1ac5 | ||
|
|
298ba99b8f | ||
|
|
65cbe3cac3 | ||
|
|
f94e8dcf04 | ||
|
|
9629303a0f | ||
|
|
020c4a3b14 | ||
|
|
2f2d1a908b | ||
|
|
03ad8a3cd0 | ||
|
|
1218e111ef | ||
|
|
78b7529172 | ||
|
|
e2bcb44687 | ||
|
|
a57c27eeec | ||
|
|
926f323a72 | ||
|
|
aa20adb22b | ||
|
|
3e0779a78d | ||
|
|
09442d65f2 | ||
|
|
415b99dab3 | ||
|
|
35b038edd3 | ||
|
|
34a95c1556 | ||
|
|
b2821420fd | ||
|
|
216a33b4cd | ||
|
|
ad0bb7ce23 | ||
|
|
17b84f6c09 | ||
|
|
7629f7f0d6 | ||
|
|
ac5f313129 | ||
|
|
329f245283 | ||
|
|
d6595ad7c9 | ||
|
|
114df7a345 | ||
|
|
e5ff5ec895 | ||
|
|
1bc02f9f6a | ||
|
|
05fa7791dc | ||
|
|
6fbdec6e83 | ||
|
|
94eb7cc592 | ||
|
|
b847e57991 | ||
|
|
07a731c4bb | ||
|
|
4ee7a1e173 | ||
|
|
ede778fb7d | ||
|
|
64a07dad38 | ||
|
|
623eb79080 | ||
|
|
51b8fd8393 | ||
|
|
6f7776e5ec | ||
|
|
a70cee9651 | ||
|
|
5e36cb91de | ||
|
|
74bf99b828 | ||
|
|
3ed0cfbd5f | ||
|
|
aca31dffb3 | ||
|
|
18b80e3781 | ||
|
|
b83174f32d | ||
|
|
80bbe47774 | ||
|
|
7726963e86 | ||
|
|
db2136b17c | ||
|
|
42043a0888 | ||
|
|
246793e873 | ||
|
|
692b0f1410 | ||
|
|
0629e1d731 | ||
|
|
9707c7bcb1 | ||
|
|
194fbef73c | ||
|
|
f7db00c1eb | ||
|
|
2f4b31ecc6 | ||
|
|
9289624688 | ||
|
|
5a8749cd5b | ||
|
|
4a7fb525d7 | ||
|
|
8888fcafa7 | ||
|
|
63a8c6d26b | ||
|
|
fc222bed7c | ||
|
|
6132ff93a2 | ||
|
|
87556aa741 | ||
|
|
43362b2832 | ||
|
|
db2d0c2e9b | ||
|
|
922d493159 | ||
|
|
c4811c3104 | ||
|
|
0ec840b3b4 | ||
|
|
0b96d08877 | ||
|
|
7abd41609f | ||
|
|
fcc193b7d1 | ||
|
|
44d74a7d8a | ||
|
|
4189855fc1 | ||
|
|
77f1abc17d | ||
|
|
96d58ccd1b | ||
|
|
823374b578 | ||
|
|
b127c1c8a7 | ||
|
|
b1ea09d901 | ||
|
|
8c1c3df232 | ||
|
|
cee08c38f4 | ||
|
|
bc8f613ba6 | ||
|
|
af584a8517 | ||
|
|
1805a956a3 | ||
|
|
74717b888e | ||
|
|
24fc88ced2 | ||
|
|
1e9dcdb7d1 | ||
|
|
7233b5f419 | ||
|
|
b9eddafe71 | ||
|
|
3a53a88139 | ||
|
|
6cbbb22ab4 | ||
|
|
b6a8af5b20 | ||
|
|
30c1a00225 | ||
|
|
b345342369 | ||
|
|
438680f3e4 | ||
|
|
740c2c4069 | ||
|
|
35429e3c46 | ||
|
|
fb265417d0 | ||
|
|
15af65b9c5 | ||
|
|
c2fdfab3ed | ||
|
|
bdd1266087 | ||
|
|
3cb713c5d7 | ||
|
|
0106939d30 | ||
|
|
e371747bae | ||
|
|
514137ecd5 | ||
|
|
4f4019b920 | ||
|
|
30fe97339b | ||
|
|
c91eb92d7f | ||
|
|
fdeaaee53d | ||
|
|
0cf1b70947 | ||
|
|
6a9f4fdce0 | ||
|
|
852c47f677 | ||
|
|
8be4af33ee | ||
|
|
daf0d59461 | ||
|
|
348f2bdde3 | ||
|
|
12b18ea7f4 | ||
|
|
381b80125a | ||
|
|
739b1f33e4 | ||
|
|
d312c0d6b3 | ||
|
|
61ec338ea8 | ||
|
|
b6cfbad35b | ||
|
|
41589d5110 | ||
|
|
4fcd61c6b1 | ||
|
|
c96ecaae4a | ||
|
|
d1f35ffb59 | ||
|
|
b348dc2b55 | ||
|
|
119e3098db | ||
|
|
4bf0615579 | ||
|
|
93c7b5e248 | ||
|
|
51eb0dd362 | ||
|
|
6a283102f9 | ||
|
|
8a5887a4d5 | ||
|
|
b605bb4c53 | ||
|
|
23b26e0b48 | ||
|
|
9efc4214b2 | ||
|
|
84b759d767 | ||
|
|
abac635737 | ||
|
|
f0ea4be2e0 | ||
|
|
010a6867f3 | ||
|
|
ee0d6b1841 | ||
|
|
0604e363f4 | ||
|
|
77d7177627 | ||
|
|
c44af99c6b | ||
|
|
4f92d2942a | ||
|
|
6013ed9fd7 | ||
|
|
8ea2e8c632 | ||
|
|
d1615bcdb6 | ||
|
|
76d920eda7 | ||
|
|
35a7d9bb15 | ||
|
|
8257e0d455 | ||
|
|
d47958b7c5 | ||
|
|
380de9fd10 | ||
|
|
ff4405589d | ||
|
|
1f072205a9 | ||
|
|
c970018fc7 | ||
|
|
5a3ebc1ba9 | ||
|
|
a97bbb0f8d | ||
|
|
46c7ff7a83 | ||
|
|
f326beb1f2 | ||
|
|
55d5c29f38 | ||
|
|
47273ef6da | ||
|
|
e5fc57af0e | ||
|
|
2921c25c62 | ||
|
|
e04e90fcbc | ||
|
|
d27eeb2b84 | ||
|
|
62ea073bad | ||
|
|
187864a4e4 | ||
|
|
a666c4a787 | ||
|
|
bda4ee0ad5 | ||
|
|
4925873a67 | ||
|
|
63ed4eb77f | ||
|
|
d03a64ced0 | ||
|
|
615a56353d | ||
|
|
45db6df1eb | ||
|
|
ac628f39ec | ||
|
|
20babc46a1 | ||
|
|
a6141ed2f0 | ||
|
|
a12bb8d0e2 | ||
|
|
5ae10e0463 | ||
|
|
ff873a274b | ||
|
|
7ad94c34e7 | ||
|
|
f8509846cf | ||
|
|
9334e607a0 | ||
|
|
f198b6eb63 | ||
|
|
cb1870e7bf | ||
|
|
384205a8c5 | ||
|
|
d9e64d2cfe | ||
|
|
5ccb0af867 | ||
|
|
da621c3524 | ||
|
|
3a28576e02 | ||
|
|
dbb7a555ce | ||
|
|
7a6991c8d9 | ||
|
|
6efac16c80 | ||
|
|
a7360a4b34 | ||
|
|
4fb9f0cb74 | ||
|
|
89f2d48f0f | ||
|
|
11dcbff707 | ||
|
|
7a6074721f | ||
|
|
959e43d8f9 | ||
|
|
f933ab4602 | ||
|
|
af78d2fd69 | ||
|
|
6f9c4aa2e0 | ||
|
|
5efa4a4751 | ||
|
|
cde336ec99 | ||
|
|
b8c51c56c2 | ||
|
|
22c28adc78 | ||
|
|
7b04f31566 | ||
|
|
0fff415c2a | ||
|
|
987538fc49 | ||
|
|
2642020398 | ||
|
|
c4a2b762e7 | ||
|
|
339d0db240 | ||
|
|
43568ccd69 | ||
|
|
fbd73f2f17 | ||
|
|
4a21ad9540 | ||
|
|
18de7e45e9 | ||
|
|
48f66aa3fe | ||
|
|
18274462ff | ||
|
|
90e4c159b1 | ||
|
|
4f57216935 | ||
|
|
e6b68305ec | ||
|
|
4ce651c0e4 | ||
|
|
db2d4e45eb | ||
|
|
ab8b73e8f8 | ||
|
|
876b8bd795 | ||
|
|
64ef6b63b7 | ||
|
|
a77984a381 | ||
|
|
31a1f5968b | ||
|
|
4ca73f0406 | ||
|
|
0909f94c20 | ||
|
|
d1c01c1ecc | ||
|
|
f8cdd608e2 | ||
|
|
2e4b83b710 | ||
|
|
6fbcbb3286 | ||
|
|
a843682f7c | ||
|
|
0611bf915b | ||
|
|
9a9cb016fa | ||
|
|
74a66fb68a | ||
|
|
aedfd3bfb8 | ||
|
|
a2e13bdeed | ||
|
|
a7d991f3cc | ||
|
|
11bc00d629 | ||
|
|
5005d7966d | ||
|
|
c2a05c71c7 | ||
|
|
51bbc1dc95 | ||
|
|
7b5e3407d1 | ||
|
|
52ab4e9376 | ||
|
|
9bfbff953b | ||
|
|
6af2d32e10 | ||
|
|
75b944ff50 | ||
|
|
bbb67198bb | ||
|
|
6be2ebde9d | ||
|
|
a4f1f25cc4 | ||
|
|
c29f6f51da | ||
|
|
edb899b9ce | ||
|
|
a8f7ecefae | ||
|
|
ec1afc2665 | ||
|
|
f12284ab2e | ||
|
|
a9ff0b5243 | ||
|
|
0a271a04cc | ||
|
|
6fa78df282 | ||
|
|
b62536fcdc | ||
|
|
9741d4ae94 | ||
|
|
68f326d9e1 | ||
|
|
76ee7291d6 | ||
|
|
d31f09035e | ||
|
|
8d7c2e6d2a | ||
|
|
9269a305fb | ||
|
|
073b315737 | ||
|
|
47c46fbe17 | ||
|
|
39572968bb | ||
|
|
4383764cae | ||
|
|
e0ef0563ce | ||
|
|
d9cf2c487d | ||
|
|
58bf4b21e7 | ||
|
|
e95c619eaa | ||
|
|
cd04c0bdb2 | ||
|
|
fd74926e76 | ||
|
|
f82ff5a4fd | ||
|
|
fa72bef8d4 | ||
|
|
2f7f1f8e83 | ||
|
|
90d083489b | ||
|
|
295cd29aeb | ||
|
|
1c844aad64 | ||
|
|
e0cd18e264 | ||
|
|
9f9faf2215 | ||
|
|
3907a60b33 | ||
|
|
e85e961af6 | ||
|
|
61cbae2697 | ||
|
|
2d512c5e47 | ||
|
|
936297a6b2 | ||
|
|
ad0f9e8cba | ||
|
|
4d20d3f543 | ||
|
|
c3e5227992 | ||
|
|
ff39445db2 | ||
|
|
77e9b0a6d1 | ||
|
|
cfd85db900 | ||
|
|
948519d460 | ||
|
|
9a67f0d1a7 | ||
|
|
17b5a60247 | ||
|
|
f42895465d | ||
|
|
9006dd5d16 | ||
|
|
27d776cdf2 | ||
|
|
1827d3d5c9 | ||
|
|
2b5782c920 | ||
|
|
6284def316 | ||
|
|
0c11078302 | ||
|
|
507fac9284 | ||
|
|
22abb9dab1 | ||
|
|
6463176bc0 | ||
|
|
b208bc4c12 | ||
|
|
53ad8c2f35 | ||
|
|
34ba0ca8d7 | ||
|
|
6d82700032 | ||
|
|
a0a991ca16 | ||
|
|
989b893bf2 | ||
|
|
d270edea75 | ||
|
|
7aa407099c | ||
|
|
abeeb37e75 | ||
|
|
1291b9a194 | ||
|
|
4a0b8c5e49 | ||
|
|
4bfa1fb821 |
@@ -1,42 +0,0 @@
|
||||
defaults: &defaults
|
||||
docker :
|
||||
- image: knqyf263/ci-trivy:latest
|
||||
environment:
|
||||
CGO_ENABLED: "1"
|
||||
|
||||
jobs:
|
||||
release:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Release
|
||||
command: goreleaser --rm-dist
|
||||
- run:
|
||||
name: Clone trivy repository
|
||||
command: git clone git@github.com:knqyf263/trivy-repo.git
|
||||
- run:
|
||||
name: Setup git settings
|
||||
command: |
|
||||
git config --global user.email "knqyf263@gmail.com"
|
||||
git config --global user.name "Teppei Fukuda"
|
||||
- run:
|
||||
name: Create rpm repository
|
||||
command: ci/deploy-rpm.sh
|
||||
- run:
|
||||
name: Import GPG key
|
||||
command: echo -e "$GPG_KEY" | gpg --import
|
||||
- run:
|
||||
name: Create deb repository
|
||||
command: ci/deploy-deb.sh
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
release:
|
||||
jobs:
|
||||
- release:
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
only: /.*/
|
||||
5
.clang-format
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
Language: Proto
|
||||
BasedOnStyle: Google
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: true
|
||||
6
.dockerignore
Normal file
@@ -0,0 +1,6 @@
|
||||
.git
|
||||
.github
|
||||
.cache
|
||||
.circleci
|
||||
integration
|
||||
imgs
|
||||
31
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Bug Report
|
||||
labels: kind/bug
|
||||
about: If something isn't working as expected.
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!--
|
||||
Briefly describe the problem you are having in a few paragraphs.
|
||||
-->
|
||||
|
||||
## What did you expect to happen?
|
||||
|
||||
|
||||
## What happened instead?
|
||||
|
||||
|
||||
## Output of run with `-debug`:
|
||||
|
||||
```
|
||||
(paste your output here)
|
||||
```
|
||||
|
||||
## Output of `trivy -v`:
|
||||
|
||||
```
|
||||
(paste your output here)
|
||||
```
|
||||
|
||||
## Additional details (base image name, container registry info...):
|
||||
9
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
name: Feature Request
|
||||
labels: kind/feature
|
||||
about: I have a suggestion (and might want to implement myself)!
|
||||
---
|
||||
|
||||
<!--
|
||||
If this is a FEATURE REQUEST, request format does not matter!
|
||||
-->
|
||||
10
.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Support Question
|
||||
labels: triage/support
|
||||
about: If you have a question about Trivy.
|
||||
---
|
||||
|
||||
<!--
|
||||
If you have a trouble, feel free to ask.
|
||||
Make sure you're not asking duplicate question by searching on the issues lists.
|
||||
-->
|
||||
10
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
34
.github/workflows/mkdocs-dev.yaml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: Deploy the dev documentation
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- mkdocs.yml
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy the dev documentation
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Checkout main
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git
|
||||
pip install mike
|
||||
pip install mkdocs-macros-plugin
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.MKDOCS_AQUA_BOT }}
|
||||
- name: Configure the git user
|
||||
run: |
|
||||
git config user.name "knqyf263"
|
||||
git config user.email "knqyf263@gmail.com"
|
||||
- name: Deploy the dev documents
|
||||
run: mike deploy --push dev
|
||||
42
.github/workflows/mkdocs-latest.yaml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: Deploy the latest documentation
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: Version to be deployed
|
||||
required: true
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy the latest documentation
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Checkout main
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git
|
||||
pip install mike
|
||||
pip install mkdocs-macros-plugin
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.MKDOCS_AQUA_BOT }}
|
||||
- name: Configure the git user
|
||||
run: |
|
||||
git config user.name "knqyf263"
|
||||
git config user.email "knqyf263@gmail.com"
|
||||
- name: Deploy the latest documents from new tag push
|
||||
if: ${{ github.event.inputs.version == '' }}
|
||||
run: |
|
||||
VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g")
|
||||
mike deploy --push --update-aliases $VERSION latest
|
||||
- name: Deploy the latest documents from manual trigger
|
||||
if: ${{ github.event.inputs.version != '' }}
|
||||
run: mike deploy --push --update-aliases ${{ github.event.inputs.version }} latest
|
||||
51
.github/workflows/publish-chart.yaml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
name: Publish Chart Helm
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'helm/trivy/**'
|
||||
workflow_dispatch:
|
||||
env:
|
||||
HELM_REP: helm-charts
|
||||
GH_OWNER: aquasecurity
|
||||
CHART_DIR: helm/trivy
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@v1
|
||||
with:
|
||||
version: v3.5.0
|
||||
- name: Install chart-releaser
|
||||
run: |
|
||||
wget https://github.com/helm/chart-releaser/releases/download/v1.1.1/chart-releaser_1.1.1_linux_amd64.tar.gz
|
||||
tar xzvf chart-releaser_1.1.1_linux_amd64.tar.gz cr
|
||||
- name: Package helm chart
|
||||
run: |
|
||||
./cr package ${{ env.CHART_DIR }}
|
||||
- name: Upload helm chart
|
||||
# Failed with upload the same version: https://github.com/helm/chart-releaser/issues/101
|
||||
continue-on-error: true
|
||||
## Upload the tar in the Releases repository
|
||||
run: |
|
||||
./cr upload -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} --token ${{ secrets.ORG_REPO_TOKEN }} -p .cr-release-packages
|
||||
- name: Index helm chart
|
||||
run: |
|
||||
./cr index -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} -c https://${{ env.GH_OWNER }}.github.io/${{ env.HELM_REP }}/ -i index.yaml
|
||||
|
||||
- name: Push index file
|
||||
uses: dmnemec/copy_file_to_another_repo_action@v1.1.1
|
||||
env:
|
||||
API_TOKEN_GITHUB: ${{ secrets.ORG_REPO_TOKEN }}
|
||||
with:
|
||||
source_file: 'index.yaml'
|
||||
destination_repo: '${{ env.GH_OWNER }}/${{ env.HELM_REP }}'
|
||||
destination_folder: '.'
|
||||
destination_branch: 'gh-pages'
|
||||
user_email: aqua-bot@users.noreply.github.com
|
||||
user_name: 'aqua-bot'
|
||||
88
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
name: Release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
env:
|
||||
GO_VERSION: "1.17"
|
||||
GH_USER: "aqua-bot"
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-18.04 # 20.04 doesn't provide createrepo for now
|
||||
env:
|
||||
DOCKER_CLI_EXPERIMENTAL: "enabled"
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install rpm reprepro createrepo distro-info
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Show available Docker Buildx platforms
|
||||
run: echo ${{ steps.buildx.outputs.platforms }}
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
- name: Login to docker.io registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USER }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Login to ghcr.io registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ env.GH_USER }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login to ECR
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: public.ecr.aws
|
||||
username: ${{ secrets.ECR_ACCESS_KEY_ID }}
|
||||
password: ${{ secrets.ECR_SECRET_ACCESS_KEY }}
|
||||
- name: Generate SBOM
|
||||
uses: CycloneDX/gh-gomod-generate-sbom@v0.3.0
|
||||
with:
|
||||
json: true
|
||||
output: bom.json
|
||||
version: ^v0
|
||||
- name: Release
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
version: v0.182.1
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
|
||||
- name: Checkout trivy-repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: ${{ github.repository_owner }}/trivy-repo
|
||||
path: trivy-repo
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.ORG_REPO_TOKEN }}
|
||||
- name: Setup git settings
|
||||
run: |
|
||||
git config --global user.email "knqyf263@gmail.com"
|
||||
git config --global user.name "Teppei Fukuda"
|
||||
- name: Create rpm repository
|
||||
run: ci/deploy-rpm.sh
|
||||
- name: Import GPG key
|
||||
run: echo -e "${{ secrets.GPG_KEY }}" | gpg --import
|
||||
- name: Create deb repository
|
||||
run: ci/deploy-deb.sh
|
||||
25
.github/workflows/scan.yaml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Scan
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
build:
|
||||
name: Scan Go vulnerabilities
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Run Trivy vulnerability scanner to scan for Critical Vulnerabilities
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
exit-code: '1'
|
||||
severity: 'CRITICAL'
|
||||
skip-dirs: integration
|
||||
|
||||
- name: Run Trivy vulnerability scanner to scan for Medium and High Vulnerabilities
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
exit-code: '0'
|
||||
severity: 'HIGH,MEDIUM'
|
||||
skip-dirs: integration
|
||||
20
.github/workflows/stale-issues.yaml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: "Stale issues"
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
jobs:
|
||||
stale:
|
||||
timeout-minutes: 1
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue is stale because it has been labeled with inactivity.'
|
||||
stale-pr-message: 'This PR is stale because it has been labeled with inactivity.'
|
||||
exempt-issue-labels: 'lifecycle/frozen,lifecycle/active,priority/critical-urgent,priority/important-soon,priority/important-longterm,priority/backlog,priority/awaiting-more-evidence'
|
||||
exempt-pr-labels: 'lifecycle/active'
|
||||
stale-pr-label: 'lifecycle/stale'
|
||||
stale-issue-label: 'lifecycle/stale'
|
||||
days-before-stale: 60
|
||||
days-before-close: 20
|
||||
103
.github/workflows/test.yaml
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
name: Test
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- 'docs/**'
|
||||
- 'mkdocs.yml'
|
||||
- 'LICENSE'
|
||||
pull_request:
|
||||
env:
|
||||
GO_VERSION: "1.17"
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
with:
|
||||
version: v1.41
|
||||
args: --deadline=30m
|
||||
|
||||
- name: Run unit tests
|
||||
run: make test
|
||||
|
||||
integration:
|
||||
name: Integration Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Run integration tests
|
||||
run: make test-integration
|
||||
|
||||
build-test:
|
||||
name: Build Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOCKER_CLI_EXPERIMENTAL: "enabled"
|
||||
steps:
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Show available Docker Buildx platforms
|
||||
run: echo ${{ steps.buildx.outputs.platforms }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
version: v0.164.0
|
||||
args: release --snapshot --rm-dist --skip-publish
|
||||
|
||||
build-documents:
|
||||
name: Documentation Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install mkdocs-material
|
||||
pip install mike
|
||||
pip install mkdocs-macros-plugin
|
||||
- name: Configure the git user
|
||||
run: |
|
||||
git config user.name "knqyf263"
|
||||
git config user.email "knqyf263@gmail.com"
|
||||
- name: Deploy the dev documents
|
||||
run: mike deploy test
|
||||
15
.gitignore
vendored
@@ -4,6 +4,10 @@
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
trivy
|
||||
|
||||
## chart release
|
||||
.cr-release-packages
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
@@ -12,3 +16,14 @@
|
||||
*.out
|
||||
|
||||
.idea
|
||||
|
||||
# Directory Cache Files
|
||||
.DS_Store
|
||||
thumbs.db
|
||||
|
||||
# test fixtures
|
||||
coverage.txt
|
||||
integration/testdata/fixtures/images
|
||||
|
||||
# SBOMs generated during CI
|
||||
/bom.json
|
||||
|
||||
71
.golangci.yaml
Normal file
@@ -0,0 +1,71 @@
|
||||
linters-settings:
|
||||
errcheck:
|
||||
check-type-assertions: true
|
||||
check-blank: true
|
||||
govet:
|
||||
check-shadowing: false
|
||||
gofmt:
|
||||
simplify: false
|
||||
revive:
|
||||
ignore-generated-header: true
|
||||
gocyclo:
|
||||
min-complexity: 10
|
||||
dupl:
|
||||
threshold: 100
|
||||
goconst:
|
||||
min-len: 3
|
||||
min-occurrences: 3
|
||||
misspell:
|
||||
locale: US
|
||||
goimports:
|
||||
local-prefixes: github.com/aquasecurity
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- structcheck
|
||||
- ineffassign
|
||||
- typecheck
|
||||
- govet
|
||||
- errcheck
|
||||
- varcheck
|
||||
- deadcode
|
||||
- revive
|
||||
- gosec
|
||||
- unconvert
|
||||
- goconst
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- goimports
|
||||
- misspell
|
||||
|
||||
run:
|
||||
skip-files:
|
||||
- ".*._mock.go$"
|
||||
- ".*._test.go$"
|
||||
- "integration/*"
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- linters:
|
||||
- gosec
|
||||
text: "G304: Potential file inclusion"
|
||||
- linters:
|
||||
- gosec
|
||||
text: "Deferring unsafe method"
|
||||
- linters:
|
||||
- gosec
|
||||
text: "G204: Subprocess launched with variable"
|
||||
- linters:
|
||||
- errcheck
|
||||
text: "Close` is not checked"
|
||||
- linters:
|
||||
- errcheck
|
||||
text: "os.*` is not checked"
|
||||
- linters:
|
||||
- golint
|
||||
text: "a blank import should be only in a main or test package"
|
||||
exclude:
|
||||
- "should have a package comment, unless it's in another file for this package"
|
||||
exclude-use-default: false
|
||||
max-same-issues: 0
|
||||
28
CONTRIBUTING.md
Normal file
@@ -0,0 +1,28 @@
|
||||
Thank you for taking interest in contributing to Trivy!
|
||||
|
||||
## Issues
|
||||
- Feel free to open issues for any reason. When you open a new issue, you'll have to select an issue kind: bug/feature/support and fill the required information based on the selected template.
|
||||
- Please spend a small amount of time giving due diligence to the issue tracker. Your issue might be a duplicate. If it is, please add your comment to the existing issue.
|
||||
- Remember that users might search for your issue 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.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
1. Every Pull Request should have an associated bug or feature issue unless you are fixing a trivial documentation issue.
|
||||
1. Your PR is more likely to be accepted if it focuses on just one change.
|
||||
1. Describe what the PR does. There's no convention enforced, but please try to be concise and descriptive. Treat the PR description as a commit message. Titles that starts with "fix"/"add"/"improve"/"remove" are good examples.
|
||||
1. Please add the associated Issue in the PR description.
|
||||
1. There's no need to add or tag reviewers.
|
||||
1. If a reviewer commented on your code or asked for changes, please remember to mark the discussion as resolved after you address it. PRs with unresolved issues should not be merged (even if the comment is unclear or requires no action from your side).
|
||||
1. Please include a comment with the results before and after your change.
|
||||
1. 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!).
|
||||
1. If your PR affects the user experience in some way, please update the Readme and the CLI help accordingly.
|
||||
|
||||
## Understand where your pull request belongs
|
||||
|
||||
Trivy is composed of several different repositories that work together:
|
||||
|
||||
- [Trivy](https://github.com/aquasecurity/trivy) is the client-side, user-facing, command line tool.
|
||||
- [vuln-list](https://github.com/aquasecurity/vuln-list) is a vulnerabilities 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](https://github.com/aquasecurity/vuln-list-update) is the code that maintains the vuln-list database.
|
||||
- [fanal](https://github.com/aquasecurity/fanal) is a library for extracting system information from containers. It is being used by Trivy to find testable subjects in the container image.
|
||||
5
Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM alpine:3.14
|
||||
RUN apk --no-cache add ca-certificates git
|
||||
COPY trivy /usr/local/bin/trivy
|
||||
COPY contrib/*.tpl contrib/
|
||||
ENTRYPOINT ["trivy"]
|
||||
214
LICENSE
@@ -1,21 +1,201 @@
|
||||
MIT License
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
Copyright (c) 2019 Teppei Fukuda
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
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:
|
||||
1. Definitions.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
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.
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
78
Makefile
Normal file
@@ -0,0 +1,78 @@
|
||||
VERSION := $(shell git describe --tags)
|
||||
LDFLAGS=-ldflags "-s -w -X=main.version=$(VERSION)"
|
||||
|
||||
GOPATH=$(shell go env GOPATH)
|
||||
GOBIN=$(GOPATH)/bin
|
||||
GOSRC=$(GOPATH)/src
|
||||
|
||||
MKDOCS_IMAGE := aquasec/mkdocs-material:dev
|
||||
MKDOCS_PORT := 8000
|
||||
|
||||
u := $(if $(update),-u)
|
||||
|
||||
$(GOBIN)/wire:
|
||||
GO111MODULE=off go get github.com/google/wire/cmd/wire
|
||||
|
||||
.PHONY: wire
|
||||
wire: $(GOBIN)/wire
|
||||
wire gen ./pkg/...
|
||||
|
||||
.PHONY: mock
|
||||
mock: $(GOBIN)/mockery
|
||||
mockery -all -inpkg -case=snake -dir $(DIR)
|
||||
|
||||
.PHONY: deps
|
||||
deps:
|
||||
go get ${u} -d
|
||||
go mod tidy
|
||||
|
||||
$(GOBIN)/golangci-lint:
|
||||
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(GOBIN) v1.41.1
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -v -short -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
integration/testdata/fixtures/images/*.tar.gz:
|
||||
git clone https://github.com/aquasecurity/trivy-test-images.git integration/testdata/fixtures/images
|
||||
|
||||
.PHONY: test-integration
|
||||
test-integration: integration/testdata/fixtures/images/*.tar.gz
|
||||
go test -v -tags=integration ./integration/...
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(GOBIN)/golangci-lint
|
||||
$(GOBIN)/golangci-lint run --timeout 5m
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
find ./ -name "*.proto" | xargs clang-format -i
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
go build $(LDFLAGS) ./cmd/trivy
|
||||
|
||||
.PHONY: protoc
|
||||
protoc:
|
||||
find ./rpc/ -name "*.proto" -type f -exec protoc --proto_path=$(GOSRC):. --twirp_out=. --twirp_opt=paths=source_relative --go_out=. --go_opt=paths=source_relative {} \;
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
go install $(LDFLAGS) ./cmd/trivy
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf integration/testdata/fixtures/images
|
||||
|
||||
$(GOBIN)/labeler:
|
||||
go install github.com/knqyf263/labeler@latest
|
||||
|
||||
.PHONY: label
|
||||
label: $(GOBIN)/labeler
|
||||
labeler apply misc/triage/labels.yaml -r aquasecurity/trivy -l 5
|
||||
|
||||
.PHONY: mkdocs-serve
|
||||
## Runs MkDocs development server to preview the documentation page
|
||||
mkdocs-serve:
|
||||
docker build -t $(MKDOCS_IMAGE) -f docs/build/Dockerfile docs/build
|
||||
docker run --name mkdocs-serve --rm -v $(PWD):/docs -p $(MKDOCS_PORT):8000 $(MKDOCS_IMAGE)
|
||||
4
NOTICE
Normal file
@@ -0,0 +1,4 @@
|
||||
Trivy
|
||||
Copyright 2019-2020 Aqua Security Software Ltd.
|
||||
|
||||
This product includes software developed by Aqua Security (https://aquasec.com).
|
||||
329
README.md
@@ -1,136 +1,219 @@
|
||||
# trivy
|
||||
<p align="center">
|
||||
<img src="docs/imgs/logo.png" width="200">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://aquasecurity.github.io/trivy/">Documentation</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues
|
||||
</p>
|
||||
|
||||
[![GitHub Release][release-img]][release]
|
||||
[![Test][test-img]][test]
|
||||
[![Go Report Card][go-report-img]][go-report]
|
||||
[![License: Apache-2.0][license-img]][license]
|
||||
[![GitHub All Releases][github-all-releases-img]][release]
|
||||
![Docker Pulls][docker-pulls]
|
||||
|
||||
[](https://github.com/knqyf263/trivy/releases/latest)
|
||||
[](https://travis-ci.org/knqyf263/trivy)
|
||||
[](https://goreportcard.com/report/github.com/knqyf263/trivy)
|
||||
[](https://github.com/knqyf263/trivy/blob/master/LICENSE)
|
||||
|
||||
# Abstract
|
||||
Scan containers
|
||||
`Trivy` (`tri` pronounced like **tri**gger, `vy` pronounced like en**vy**) is a simple and comprehensive scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues.
|
||||
`Trivy` detects vulnerabilities of OS packages (Alpine, RHEL, CentOS, etc.) and language-specific packages (Bundler, Composer, npm, yarn, etc.).
|
||||
In addition, `Trivy` scans Infrastructure as Code (IaC) files such as Terraform, Dockerfile and Kubernetes, to detect potential configuration issues that expose your deployments to the risk of attack.
|
||||
`Trivy` is easy to use. Just install the binary and you're ready to scan.
|
||||
|
||||
<p align="center">
|
||||
<img src="docs/imgs/overview.png" width="800" alt="Trivy Overview">
|
||||
</p>
|
||||
|
||||
### Demo: Vulnerability Detection (Container Image)
|
||||
<p align="center">
|
||||
<img src="docs/imgs/vuln-demo.gif" width="1000" alt="Vulnerability Detection">
|
||||
</p>
|
||||
|
||||
### Demo: Misconfiguration Detection (IaC Files)
|
||||
<p align="center">
|
||||
<img src="docs/imgs/misconf-demo.gif" width="1000" alt="Misconfiguration Detection">
|
||||
</p>
|
||||
|
||||
# Quick Start
|
||||
## Scan Image for Vulnerabilities
|
||||
Simply specify an image name (and a tag).
|
||||
|
||||
```
|
||||
$ trivy image [YOUR_IMAGE_NAME]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ trivy image python:3.4-alpine
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
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 |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
</details>
|
||||
|
||||
## Scan Filesystem for Vulnerabilities and Misconfigurations
|
||||
Simply specify a directory to scan.
|
||||
|
||||
```bash
|
||||
$ trivy fs --security-checks vuln,config [YOUR_PROJECT_DIR]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
$ trivy fs --security-checks vuln,config myproject/
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```bash
|
||||
2021-07-09T12:03:27.564+0300 INFO Number of language-specific files: 1
|
||||
2021-07-09T12:03:27.564+0300 INFO Detecting pipenv vulnerabilities...
|
||||
2021-07-09T12:03:27.566+0300 INFO Detected config files: 1
|
||||
|
||||
Pipfile.lock (pipenv)
|
||||
=====================
|
||||
Total: 1 (HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+----------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | 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 |
|
||||
| | | | | | -->avd.aquasec.com/nvd/cve-2021-21240 |
|
||||
+----------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
```
|
||||
</details>
|
||||
|
||||
## Scan Directory for Misconfigurations
|
||||
|
||||
Simply specify a directory containing IaC files such as Terraform and Dockerfile.
|
||||
|
||||
```
|
||||
$ trivy config [YOUR_IAC_DIR]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ ls build/
|
||||
Dockerfile
|
||||
$ trivy config ./build
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2021-07-09T10:06:29.188+0300 INFO Need to update the built-in policies
|
||||
2021-07-09T10:06:29.188+0300 INFO Downloading the built-in policies...
|
||||
2021-07-09T10:06:30.520+0300 INFO Detected config files: 1
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
# Features
|
||||
|
||||
# Installation
|
||||
- Comprehensive vulnerability detection
|
||||
- OS packages (Alpine Linux, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
|
||||
- **Language-specific packages** (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, Maven, and Go)
|
||||
- Misconfiguration detection (IaC scanning)
|
||||
- A wide variety of built-in policies are provided **out of the box**
|
||||
- Kubernetes, Docker, Terraform, and more coming soon
|
||||
- Support custom policies
|
||||
- Simple
|
||||
- Specify only an image name, a path to config files, or an artifact name
|
||||
- Fast
|
||||
- The first scan will finish within 10 seconds (depending on your network). Consequent scans will finish in single seconds.
|
||||
- Easy installation
|
||||
- `apt-get install`, `yum install` and `brew install` are possible.
|
||||
- **No pre-requisites** such as installation of DB, libraries, etc.
|
||||
- High accuracy
|
||||
- **Especially [Alpine Linux][alpine] and RHEL/CentOS**
|
||||
- Other OSes are also high
|
||||
- DevSecOps
|
||||
- **Suitable for CI** such as GitHub Actions, Jenkins, GitLab CI, etc.
|
||||
- Support multiple targets
|
||||
- container image, local filesystem and remote git repository
|
||||
|
||||
## RHEL/CentOS
|
||||
# Integrations
|
||||
- [GitHub Actions][action]
|
||||
- [Visual Studio Code][vscode]
|
||||
|
||||
Add repository setting to `/etc/yum.repos.d`.
|
||||
# Documentation
|
||||
The official documentation, which provides detailed installation, configuration, and quick start guides, is available at https://aquasecurity.github.io/trivy/.
|
||||
|
||||
```
|
||||
$ sudo vim /etc/yum.repos.d/trivy.repo
|
||||
[trivy]
|
||||
name=Trivy repository
|
||||
baseurl=https://knqyf263.github.io/trivy-repo/rpm/releases/$releasever/$basearch/
|
||||
gpgcheck=0
|
||||
enabled=1
|
||||
$ sudo yum -y update
|
||||
$ sudo yum -y install trivy
|
||||
```
|
||||
---
|
||||
|
||||
## Debian/Ubuntu
|
||||
Trivy is an [Aqua Security][aquasec] open source project.
|
||||
Learn about our open source work and portfolio [here][oss].
|
||||
Contact us about any matter by opening a GitHub Discussion [here][discussions]
|
||||
|
||||
Replace `[CODE_NAME]` with your code name
|
||||
[test]: https://github.com/aquasecurity/trivy/actions/workflows/test.yaml
|
||||
[test-img]: https://github.com/aquasecurity/trivy/actions/workflows/test.yaml/badge.svg
|
||||
[go-report]: https://goreportcard.com/report/github.com/aquasecurity/trivy
|
||||
[go-report-img]: https://goreportcard.com/badge/github.com/aquasecurity/trivy
|
||||
[release]: https://github.com/aquasecurity/trivy/releases
|
||||
[release-img]: https://img.shields.io/github/release/aquasecurity/trivy.svg?logo=github
|
||||
[github-all-releases-img]: https://img.shields.io/github/downloads/aquasecurity/trivy/total?logo=github
|
||||
[docker-pulls]: https://img.shields.io/docker/pulls/aquasec/trivy?logo=docker&label=docker%20pulls%20%2F%20trivy
|
||||
[license]: https://github.com/aquasecurity/trivy/blob/main/LICENSE
|
||||
[license-img]: https://img.shields.io/badge/License-Apache%202.0-blue.svg
|
||||
|
||||
CODE_NAME: wheezy, jessie, stretch, buster, trusty, xenial, bionic
|
||||
[alpine]: https://ariadne.space/2021/06/08/the-vulnerability-remediation-lifecycle-of-alpine-containers/
|
||||
[action]: https://github.com/aquasecurity/trivy-action
|
||||
[vscode]: https://github.com/aquasecurity/trivy-vscode-extension
|
||||
|
||||
```
|
||||
$ sudo apt-get install apt-transport-https gnupg
|
||||
$ wget -qO - https://knqyf263.github.io/trivy-repo/deb/public.key | sudo apt-key add -
|
||||
$ echo deb https://knqyf263.github.io/trivy-repo/deb [CODE_NAME] main | sudo tee -a /etc/apt/sources.list
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install trivy
|
||||
```
|
||||
|
||||
## Mac OS X / Homebrew
|
||||
You can use homebrew on OS X.
|
||||
```
|
||||
$ brew tap knqyf263/trivy
|
||||
$ brew install knqyf263/trivy/trivy
|
||||
```
|
||||
|
||||
## Binary (Including Windows)
|
||||
Go to [the releases page](https://github.com/knqyf263/trivy/releases), find the version you want, and download the zip file. Unpack the zip file, and put the binary to somewhere you want (on UNIX-y systems, /usr/local/bin or the like). Make sure it has execution bits turned on.
|
||||
|
||||
## From source
|
||||
|
||||
```sh
|
||||
$ go get -u github.com/knqyf263/trivy
|
||||
```
|
||||
|
||||
# Examples
|
||||
|
||||
# Usage
|
||||
|
||||
```
|
||||
$ trivy -h
|
||||
NAME:
|
||||
trivy - A simple and comprehensive vulnerability scanner for containers
|
||||
USAGE:
|
||||
main [options] image_name
|
||||
VERSION:
|
||||
0.0.1
|
||||
OPTIONS:
|
||||
--format value, -f value format (table, json) (default: "table")
|
||||
--input value, -i value input file path instead of image name
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN")
|
||||
--output value, -o value output file name
|
||||
--skip-update skip db update
|
||||
--clean, -c clean all cache
|
||||
--debug, -d debug mode
|
||||
--help, -h show help
|
||||
--version, -v print the version
|
||||
```
|
||||
|
||||
# Q&A
|
||||
## Homebrew
|
||||
### Error: Your macOS keychain GitHub credentials do not have sufficient scope!
|
||||
|
||||
```
|
||||
$ brew tap knqyf263/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
|
||||
```
|
||||
|
||||
### Error: knqyf263/trivy/trivy 64 already installed
|
||||
|
||||
```
|
||||
$ brew upgrade
|
||||
...
|
||||
Error: knqyf263/trivy/trivy 64 already installed
|
||||
```
|
||||
|
||||
Try:
|
||||
|
||||
```
|
||||
$ brew unlink trivy && brew uninstall trivy
|
||||
($ rm -rf /usr/local/Cellar/trivy/64)
|
||||
$ brew install knqyf263/trivy/trivy
|
||||
```
|
||||
|
||||
# Contribute
|
||||
|
||||
1. fork a repository: github.com/knqyf263/trivy to github.com/you/repo
|
||||
2. get original code: `go get github.com/knqyf263/trivy`
|
||||
3. work on original code
|
||||
4. add remote to your repo: git remote add myfork https://github.com/you/repo.git
|
||||
5. push your changes: git push myfork
|
||||
6. create a new Pull Request
|
||||
|
||||
- see [GitHub and Go: forking, pull requests, and go-getting](http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html)
|
||||
|
||||
----
|
||||
|
||||
# License
|
||||
MIT
|
||||
|
||||
# Author
|
||||
Teppei Fukuda (knqyf263)
|
||||
[aquasec]: https://aquasec.com
|
||||
[oss]: https://www.aquasec.com/products/open-source-projects/
|
||||
[discussions]: https://github.com/aquasecurity/trivy/discussions
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
FROM bepsays/ci-goreleaser:1.12-2
|
||||
|
||||
RUN apt-get -y update \
|
||||
&& apt-get -y install vim rpm reprepro createrepo \
|
||||
&& wget https://dl.bintray.com/homebrew/mirror/berkeley-db-18.1.32.tar.gz \
|
||||
|
||||
# Berkeley DB
|
||||
&& tar zxvf berkeley-db-18.1.32.tar.gz \
|
||||
&& cd db-18.1.32/build_unix \
|
||||
|
||||
# Linux
|
||||
&& ../dist/configure --prefix=/usr/local --host=x86_64-linux \
|
||||
&& make \
|
||||
&& make install \
|
||||
|
||||
# Darwin
|
||||
&& make clean \
|
||||
&& ../dist/configure --prefix=/usr/local --host=x86_64-apple-darwin15 \
|
||||
&& make \
|
||||
&& make install
|
||||
@@ -1,17 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
RELEASES=(wheezy jessie stretch buster trusty xenial bionic)
|
||||
DEBIAN_RELEASES=$(debian-distro-info --supported)
|
||||
UBUNTU_RELEASES=$(ubuntu-distro-info --supported-esm)
|
||||
|
||||
cd trivy-repo/deb
|
||||
|
||||
for release in ${RELEASES[@]}; do
|
||||
echo "Adding deb package to $release"
|
||||
for release in ${DEBIAN_RELEASES[@]} ${UBUNTU_RELEASES[@]}; do
|
||||
echo "Removing deb package of $release"
|
||||
reprepro -A i386 remove $release trivy
|
||||
reprepro -A amd64 remove $release trivy
|
||||
done
|
||||
|
||||
for release in ${DEBIAN_RELEASES[@]} ${UBUNTU_RELEASES[@]}; do
|
||||
echo "Adding deb package to $release"
|
||||
reprepro includedeb $release ../../dist/*Linux-64bit.deb
|
||||
reprepro includedeb $release ../../dist/*Linux-32bit.deb
|
||||
done
|
||||
|
||||
git add .
|
||||
git commit -m "Update deb packages"
|
||||
git push origin master
|
||||
git push origin main
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
RPM_EL6=$(find dist/ -type f -name "*64bit.rpm" -printf "%f\n" | head -n1 | sed -e 's/_/-/g' -e 's/-Linux/.el6/' -e 's/-64bit/.x86_64/')
|
||||
RPM_EL7=$(find dist/ -type f -name "*64bit.rpm" -printf "%f\n" | head -n1 | sed -e 's/_/-/g' -e 's/-Linux/.el7/' -e 's/-64bit/.x86_64/')
|
||||
function create_rpm_repo () {
|
||||
version=$1
|
||||
rpm_path=rpm/releases/${version}/x86_64
|
||||
|
||||
RPM_EL=$(find ../dist/ -type f -name "*64bit.rpm" -printf "%f\n" | head -n1 | sed -e "s/_/-/g" -e "s/-Linux/.el$version/" -e "s/-64bit/.x86_64/")
|
||||
echo $RPM_EL
|
||||
|
||||
mkdir -p $rpm_path
|
||||
cp ../dist/*64bit.rpm ${rpm_path}/${RPM_EL}
|
||||
|
||||
createrepo --update $rpm_path
|
||||
}
|
||||
|
||||
cd trivy-repo
|
||||
mkdir -p rpm/releases/6/x86_64
|
||||
mkdir -p rpm/releases/7/x86_64
|
||||
|
||||
cd rpm
|
||||
cp ../../dist/*64bit.rpm releases/6/x86_64/${RPM_EL6}
|
||||
cp ../../dist/*64bit.rpm releases/7/x86_64/${RPM_EL7}
|
||||
|
||||
createrepo --update releases/6/x86_64/
|
||||
createrepo --update releases/7/x86_64/
|
||||
VERSIONS=(5 6 7 8)
|
||||
for version in ${VERSIONS[@]}; do
|
||||
echo "Processing RHEL/CentOS $version..."
|
||||
create_rpm_repo $version
|
||||
done
|
||||
|
||||
git add .
|
||||
git commit -m "Update rpm packages"
|
||||
git push origin master
|
||||
git push origin main
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/knqyf263/trivy/pkg/vulnsrc/vulnerability"
|
||||
|
||||
"github.com/knqyf263/trivy/pkg/remic"
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/knqyf263/trivy/pkg/log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cli.AppHelpTemplate = `NAME:
|
||||
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
|
||||
USAGE:
|
||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||
VERSION:
|
||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||
DESCRIPTION:
|
||||
{{.Description}}{{end}}{{if len .Authors}}
|
||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||
{{range $index, $author := .Authors}}{{if $index}}
|
||||
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
|
||||
OPTIONS:
|
||||
{{range $index, $option := .VisibleFlags}}{{if $index}}
|
||||
{{end}}{{$option}}{{end}}{{end}}
|
||||
`
|
||||
app := cli.NewApp()
|
||||
app.Name = "remic"
|
||||
app.Version = "0.0.1"
|
||||
app.ArgsUsage = "file"
|
||||
|
||||
app.Usage = "A simple and fast tool for detecting vulnerabilities in application dependencies"
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format, f",
|
||||
Value: "table",
|
||||
Usage: "format (table, json)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "severity, s",
|
||||
Value: strings.Join(vulnerability.SeverityNames, ","),
|
||||
Usage: "severity of vulnerabilities to be displayed",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "output, o",
|
||||
Usage: "output file name",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "debug, d",
|
||||
Usage: "debug mode",
|
||||
},
|
||||
}
|
||||
|
||||
app.Action = func(c *cli.Context) error {
|
||||
return remic.Run(c)
|
||||
}
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
log.Logger.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,9 @@ package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/knqyf263/trivy/pkg/vulnsrc/vulnerability"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/knqyf263/trivy/pkg"
|
||||
"github.com/knqyf263/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/commands"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -17,68 +12,9 @@ var (
|
||||
)
|
||||
|
||||
func main() {
|
||||
cli.AppHelpTemplate = `NAME:
|
||||
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
|
||||
USAGE:
|
||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||
VERSION:
|
||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||
DESCRIPTION:
|
||||
{{.Description}}{{end}}{{if len .Authors}}
|
||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||
{{range $index, $author := .Authors}}{{if $index}}
|
||||
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
|
||||
OPTIONS:
|
||||
{{range $index, $option := .VisibleFlags}}{{if $index}}
|
||||
{{end}}{{$option}}{{end}}{{end}}
|
||||
`
|
||||
app := cli.NewApp()
|
||||
app.Name = "trivy"
|
||||
app.Version = version
|
||||
app.ArgsUsage = "image_name"
|
||||
|
||||
app.Usage = "A simple and comprehensive vulnerability scanner for containers"
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format, f",
|
||||
Value: "table",
|
||||
Usage: "format (table, json)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "input, i",
|
||||
Value: "",
|
||||
Usage: "input file path instead of image name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "severity, s",
|
||||
Value: strings.Join(vulnerability.SeverityNames, ","),
|
||||
Usage: "severities of vulnerabilities to be displayed (comma separated)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "output, o",
|
||||
Usage: "output file name",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "skip-update",
|
||||
Usage: "skip db update",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "clean, c",
|
||||
Usage: "clean all cache",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "debug, d",
|
||||
Usage: "debug mode",
|
||||
},
|
||||
}
|
||||
|
||||
app.Action = func(c *cli.Context) error {
|
||||
return pkg.Run(c)
|
||||
}
|
||||
|
||||
app := commands.NewApp(version)
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
log.Logger.Fatal(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
29
contrib/Trivy.gitlab-ci.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
Trivy_container_scanning:
|
||||
stage: test
|
||||
image:
|
||||
name: alpine:3.11
|
||||
variables:
|
||||
# Override the GIT_STRATEGY variable in your `.gitlab-ci.yml` file and set it to `fetch` if you want to provide a `clair-whitelist.yml`
|
||||
# file. See https://docs.gitlab.com/ee/user/application_security/container_scanning/index.html#overriding-the-container-scanning-template
|
||||
# for details
|
||||
GIT_STRATEGY: none
|
||||
IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
|
||||
allow_failure: true
|
||||
before_script:
|
||||
- export TRIVY_VERSION=${TRIVY_VERSION:-v0.19.2}
|
||||
- apk add --no-cache curl docker-cli
|
||||
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
|
||||
- curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin ${TRIVY_VERSION}
|
||||
- curl -sSL -o /tmp/trivy-gitlab.tpl https://github.com/aquasecurity/trivy/raw/${TRIVY_VERSION}/contrib/gitlab.tpl
|
||||
script:
|
||||
- trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --format template --template "@/tmp/trivy-gitlab.tpl" -o gl-container-scanning-report.json $IMAGE
|
||||
cache:
|
||||
paths:
|
||||
- .trivycache/
|
||||
artifacts:
|
||||
reports:
|
||||
container_scanning: gl-container-scanning-report.json
|
||||
dependencies: []
|
||||
only:
|
||||
refs:
|
||||
- branches
|
||||
66
contrib/asff.tpl
Normal file
@@ -0,0 +1,66 @@
|
||||
[
|
||||
{{- $t_first := true -}}
|
||||
{{- range . -}}
|
||||
{{- $target := .Target -}}
|
||||
{{- range .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{- else -}}
|
||||
,
|
||||
{{- end -}}
|
||||
{{- $severity := .Severity -}}
|
||||
{{- if eq $severity "UNKNOWN" -}}
|
||||
{{- $severity = "INFORMATIONAL" -}}
|
||||
{{- end -}}
|
||||
{{- $description := .Description -}}
|
||||
{{- if gt (len $description ) 1021 -}}
|
||||
{{- $description = (substr 0 1021 $description) | printf "%v .." -}}
|
||||
{{- end}}
|
||||
{
|
||||
"SchemaVersion": "2018-10-08",
|
||||
"Id": "{{ $target }}/{{ .VulnerabilityID }}",
|
||||
"ProductArn": "arn:aws:securityhub:{{ getEnv "AWS_REGION" }}::product/aquasecurity/aquasecurity",
|
||||
"GeneratorId": "Trivy",
|
||||
"AwsAccountId": "{{ getEnv "AWS_ACCOUNT_ID" }}",
|
||||
"Types": [ "Software and Configuration Checks/Vulnerabilities/CVE" ],
|
||||
"CreatedAt": "{{ getCurrentTime }}",
|
||||
"UpdatedAt": "{{ getCurrentTime }}",
|
||||
"Severity": {
|
||||
"Label": "{{ $severity }}"
|
||||
},
|
||||
"Title": "Trivy found a vulnerability to {{ .VulnerabilityID }} in container {{ $target }}",
|
||||
"Description": {{ escapeString $description | printf "%q" }},
|
||||
"Remediation": {
|
||||
"Recommendation": {
|
||||
"Text": "More information on this vulnerability is provided in the hyperlink",
|
||||
"Url": "{{ .PrimaryURL }}"
|
||||
}
|
||||
},
|
||||
"ProductFields": { "Product Name": "Trivy" },
|
||||
"Resources": [
|
||||
{
|
||||
"Type": "Container",
|
||||
"Id": "{{ $target }}",
|
||||
"Partition": "aws",
|
||||
"Region": "{{ getEnv "AWS_REGION" }}",
|
||||
"Details": {
|
||||
"Container": { "ImageName": "{{ $target }}" },
|
||||
"Other": {
|
||||
"CVE ID": "{{ .VulnerabilityID }}",
|
||||
"CVE Title": {{ .Title | printf "%q" }},
|
||||
"PkgName": "{{ .PkgName }}",
|
||||
"Installed Package": "{{ .InstalledVersion }}",
|
||||
"Patched Package": "{{ .FixedVersion }}",
|
||||
"NvdCvssScoreV3": "{{ (index .CVSS "nvd").V3Score }}",
|
||||
"NvdCvssVectorV3": "{{ (index .CVSS "nvd").V3Vector }}",
|
||||
"NvdCvssScoreV2": "{{ (index .CVSS "nvd").V2Score }}",
|
||||
"NvdCvssVectorV2": "{{ (index .CVSS "nvd").V2Vector }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"RecordState": "ACTIVE"
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
]
|
||||
94
contrib/example_policy/advanced.rego
Normal file
@@ -0,0 +1,94 @@
|
||||
package trivy
|
||||
|
||||
import data.lib.trivy
|
||||
|
||||
default ignore = false
|
||||
|
||||
nvd_v3_vector = v {
|
||||
v := input.CVSS.nvd.v3
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which requires high privilege
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.PrivilegesRequired == "High"
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which requires user interaction
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.UserInteraction == "Required"
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.PkgName == "openssl"
|
||||
|
||||
# Split CVSSv3 vector
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
|
||||
# Evaluate Attack Vector
|
||||
ignore_attack_vectors := {"Physical", "Local"}
|
||||
cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.PkgName == "openssl"
|
||||
|
||||
# Evaluate severity
|
||||
input.Severity == {"LOW", "MEDIUM", "HIGH"}[_]
|
||||
|
||||
# Evaluate CWE-ID
|
||||
deny_cwe_ids := {
|
||||
"CWE-119", # Improper Restriction of Operations within the Bounds of a Memory Buffer
|
||||
"CWE-200", # Exposure of Sensitive Information to an Unauthorized Actor
|
||||
}
|
||||
|
||||
count({x | x := input.CweIDs[_]; x == deny_cwe_ids[_]}) == 0
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.PkgName == "bash"
|
||||
|
||||
# Split CVSSv3 vector
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
|
||||
# Evaluate Attack Vector
|
||||
ignore_attack_vectors := {"Physical", "Local", "Adjacent"}
|
||||
cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
|
||||
# Evaluate severity
|
||||
input.Severity == {"LOW", "MEDIUM", "HIGH"}[_]
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.PkgName == "django"
|
||||
|
||||
# Split CVSSv3 vector
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
|
||||
# Evaluate Attack Vector
|
||||
ignore_attack_vectors := {"Physical", "Local"}
|
||||
cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
|
||||
# Evaluate severity
|
||||
input.Severity == {"LOW", "MEDIUM"}[_]
|
||||
|
||||
# Evaluate CWE-ID
|
||||
deny_cwe_ids := {
|
||||
"CWE-89", # SQL Injection
|
||||
"CWE-78", # OS Command Injection
|
||||
}
|
||||
|
||||
count({x | x := input.CweIDs[_]; x == deny_cwe_ids[_]}) == 0
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.PkgName == "jquery"
|
||||
|
||||
# Split CVSSv3 vector
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
|
||||
# Evaluate CWE-ID
|
||||
deny_cwe_ids := {"CWE-79"} # XSS
|
||||
count({x | x := input.CweIDs[_]; x == deny_cwe_ids[_]}) == 0
|
||||
}
|
||||
45
contrib/example_policy/basic.rego
Normal file
@@ -0,0 +1,45 @@
|
||||
package trivy
|
||||
|
||||
import data.lib.trivy
|
||||
|
||||
default ignore = false
|
||||
|
||||
ignore_pkgs := {"bash", "bind-license", "rpm", "vim", "vim-minimal"}
|
||||
|
||||
ignore_severities := {"LOW", "MEDIUM"}
|
||||
|
||||
nvd_v3_vector = v {
|
||||
v := input.CVSS.nvd.v3
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.PkgName == ignore_pkgs[_]
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.Severity == ignore_severities[_]
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which is not remotely exploitable
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.AttackVector != "Network"
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which requires high privilege
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.PrivilegesRequired == "High"
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which requires user interaction
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.UserInteraction == "Required"
|
||||
}
|
||||
|
||||
# Ignore CSRF
|
||||
ignore {
|
||||
# https://cwe.mitre.org/data/definitions/352.html
|
||||
input.CweIDs[_] == "CWE-352"
|
||||
}
|
||||
38
contrib/gitlab-codequality.tpl
Normal file
@@ -0,0 +1,38 @@
|
||||
{{- /* Template based on https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#data-types */ -}}
|
||||
[
|
||||
{{- $t_first := true }}
|
||||
{{- range . }}
|
||||
{{- $target := .Target }}
|
||||
{{- range .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{ else -}}
|
||||
,
|
||||
{{- end }}
|
||||
{
|
||||
"type": "issue",
|
||||
"check_name": "container_scanning",
|
||||
"categories": [ "Security" ],
|
||||
"description": "{{ .VulnerabilityID }}: {{ .Title }}",
|
||||
"content": {{ .Description | printf "%q" }},
|
||||
"severity": {{ if eq .Severity "LOW" -}}
|
||||
"info"
|
||||
{{- else if eq .Severity "MEDIUM" -}}
|
||||
"minor"
|
||||
{{- else if eq .Severity "HIGH" -}}
|
||||
"major"
|
||||
{{- else if eq .Severity "CRITICAL" -}}
|
||||
"critical"
|
||||
{{- else -}}
|
||||
"info"
|
||||
{{- end }},
|
||||
"location": {
|
||||
"path": "{{ .PkgName }}-{{ .InstalledVersion }}",
|
||||
"lines": {
|
||||
"begin": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
]
|
||||
83
contrib/gitlab.tpl
Normal file
@@ -0,0 +1,83 @@
|
||||
{{- /* Template based on https://docs.gitlab.com/ee/user/application_security/container_scanning/#reports-json-format */ -}}
|
||||
{
|
||||
"version": "2.3",
|
||||
"vulnerabilities": [
|
||||
{{- $t_first := true }}
|
||||
{{- range . }}
|
||||
{{- $target := .Target }}
|
||||
{{- range .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{ else -}}
|
||||
,
|
||||
{{- end }}
|
||||
{
|
||||
"id": "{{ .VulnerabilityID }}",
|
||||
"category": "container_scanning",
|
||||
"message": {{ .Title | printf "%q" }},
|
||||
"description": {{ .Description | printf "%q" }},
|
||||
{{- /* cve is a deprecated key, use id instead */}}
|
||||
"cve": "{{ .VulnerabilityID }}",
|
||||
"severity": {{ if eq .Severity "UNKNOWN" -}}
|
||||
"Unknown"
|
||||
{{- else if eq .Severity "LOW" -}}
|
||||
"Low"
|
||||
{{- else if eq .Severity "MEDIUM" -}}
|
||||
"Medium"
|
||||
{{- else if eq .Severity "HIGH" -}}
|
||||
"High"
|
||||
{{- else if eq .Severity "CRITICAL" -}}
|
||||
"Critical"
|
||||
{{- else -}}
|
||||
"{{ .Severity }}"
|
||||
{{- end }},
|
||||
{{- /* TODO: Define confidence */}}
|
||||
"confidence": "Unknown",
|
||||
"solution": {{ if .FixedVersion -}}
|
||||
"Upgrade {{ .PkgName }} to {{ .FixedVersion }}"
|
||||
{{- else -}}
|
||||
"No solution provided"
|
||||
{{- end }},
|
||||
"scanner": {
|
||||
"id": "trivy",
|
||||
"name": "trivy"
|
||||
},
|
||||
"location": {
|
||||
"dependency": {
|
||||
"package": {
|
||||
"name": "{{ .PkgName }}"
|
||||
},
|
||||
"version": "{{ .InstalledVersion }}"
|
||||
},
|
||||
{{- /* TODO: No mapping available - https://github.com/aquasecurity/trivy/issues/332 */}}
|
||||
"operating_system": "Unknown",
|
||||
"image": "{{ $target }}"
|
||||
},
|
||||
"identifiers": [
|
||||
{
|
||||
{{- /* TODO: Type not extractable - https://github.com/aquasecurity/trivy-db/pull/24 */}}
|
||||
"type": "cve",
|
||||
"name": "{{ .VulnerabilityID }}",
|
||||
"value": "{{ .VulnerabilityID }}",
|
||||
"url": "{{ .PrimaryURL }}"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{{- $l_first := true -}}
|
||||
{{- range .References -}}
|
||||
{{- if $l_first -}}
|
||||
{{- $l_first = false }}
|
||||
{{- else -}}
|
||||
,
|
||||
{{- end -}}
|
||||
{
|
||||
"url": "{{ . }}"
|
||||
}
|
||||
{{- end }}
|
||||
]
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
],
|
||||
"remediations": []
|
||||
}
|
||||
123
contrib/html.tpl
Normal file
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
{{- if . }}
|
||||
<style>
|
||||
* {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
.group-header th {
|
||||
font-size: 200%;
|
||||
}
|
||||
.sub-header th {
|
||||
font-size: 150%;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
white-space: nowrap;
|
||||
padding: .3em;
|
||||
}
|
||||
table {
|
||||
margin: 0 auto;
|
||||
}
|
||||
.severity {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
color: #fafafa;
|
||||
}
|
||||
.severity-LOW .severity { background-color: #5fbb31; }
|
||||
.severity-MEDIUM .severity { background-color: #e9c600; }
|
||||
.severity-HIGH .severity { background-color: #ff8800; }
|
||||
.severity-CRITICAL .severity { background-color: #e40000; }
|
||||
.severity-UNKNOWN .severity { background-color: #747474; }
|
||||
.severity-LOW { background-color: #5fbb3160; }
|
||||
.severity-MEDIUM { background-color: #e9c60060; }
|
||||
.severity-HIGH { background-color: #ff880060; }
|
||||
.severity-CRITICAL { background-color: #e4000060; }
|
||||
.severity-UNKNOWN { background-color: #74747460; }
|
||||
table tr td:first-of-type {
|
||||
font-weight: bold;
|
||||
}
|
||||
.links a,
|
||||
.links[data-more-links=on] a {
|
||||
display: block;
|
||||
}
|
||||
.links[data-more-links=off] a:nth-of-type(1n+5) {
|
||||
display: none;
|
||||
}
|
||||
a.toggle-more-links { cursor: pointer; }
|
||||
</style>
|
||||
<title>{{- escapeXML ( index . 0 ).Target }} - Trivy Report - {{ getCurrentTime }}</title>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelectorAll('td.links').forEach(function(linkCell) {
|
||||
var links = [].concat.apply([], linkCell.querySelectorAll('a'));
|
||||
[].sort.apply(links, function(a, b) {
|
||||
return a.href > b.href ? 1 : -1;
|
||||
});
|
||||
links.forEach(function(link, idx) {
|
||||
if (links.length > 3 && 3 === idx) {
|
||||
var toggleLink = document.createElement('a');
|
||||
toggleLink.innerText = "Toggle more links";
|
||||
toggleLink.href = "#toggleMore";
|
||||
toggleLink.setAttribute("class", "toggle-more-links");
|
||||
linkCell.appendChild(toggleLink);
|
||||
}
|
||||
linkCell.appendChild(link);
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('a.toggle-more-links').forEach(function(toggleLink) {
|
||||
toggleLink.onclick = function() {
|
||||
var expanded = toggleLink.parentElement.getAttribute("data-more-links");
|
||||
toggleLink.parentElement.setAttribute("data-more-links", "on" === expanded ? "off" : "on");
|
||||
return false;
|
||||
};
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{- escapeXML ( index . 0 ).Target }} - Trivy Report - {{ getCurrentTime }}</h1>
|
||||
<table>
|
||||
{{- range . }}
|
||||
<tr class="group-header"><th colspan="6">{{ escapeXML .Type }}</th></tr>
|
||||
{{- if (eq (len .Vulnerabilities) 0) }}
|
||||
<tr><th colspan="6">No Vulnerabilities found</th></tr>
|
||||
{{- else }}
|
||||
<tr class="sub-header">
|
||||
<th>Package</th>
|
||||
<th>Vulnerability ID</th>
|
||||
<th>Severity</th>
|
||||
<th>Installed Version</th>
|
||||
<th>Fixed Version</th>
|
||||
<th>Links</th>
|
||||
</tr>
|
||||
{{- range .Vulnerabilities }}
|
||||
<tr class="severity-{{ escapeXML .Vulnerability.Severity }}">
|
||||
<td class="pkg-name">{{ escapeXML .PkgName }}</td>
|
||||
<td>{{ escapeXML .VulnerabilityID }}</td>
|
||||
<td class="severity">{{ escapeXML .Vulnerability.Severity }}</td>
|
||||
<td class="pkg-version">{{ escapeXML .InstalledVersion }}</td>
|
||||
<td>{{ escapeXML .FixedVersion }}</td>
|
||||
<td class="links" data-more-links="off">
|
||||
{{- range .Vulnerability.References }}
|
||||
<a href={{ escapeXML . | printf "%q" }}>{{ escapeXML . }}</a>
|
||||
{{- end }}
|
||||
</td>
|
||||
</tr>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</table>
|
||||
{{- else }}
|
||||
</head>
|
||||
<body>
|
||||
<h1>Trivy Returned Empty Report</h1>
|
||||
{{- end }}
|
||||
</body>
|
||||
</html>
|
||||
413
contrib/install.sh
Executable file
@@ -0,0 +1,413 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
# Code generated by godownloader on 2020-01-14T10:03:29Z. DO NOT EDIT.
|
||||
#
|
||||
|
||||
usage() {
|
||||
this=$1
|
||||
cat <<EOF
|
||||
$this: download go binaries for aquasecurity/trivy
|
||||
|
||||
Usage: $this [-b] bindir [-d] [tag]
|
||||
-b sets bindir or installation directory, Defaults to ./bin
|
||||
-d turns on debug logging
|
||||
[tag] is a tag from
|
||||
https://github.com/aquasecurity/trivy/releases
|
||||
If tag is missing, then the latest will be used.
|
||||
|
||||
Generated by godownloader
|
||||
https://github.com/goreleaser/godownloader
|
||||
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
|
||||
parse_args() {
|
||||
#BINDIR is ./bin unless set be ENV
|
||||
# over-ridden by flag below
|
||||
|
||||
BINDIR=${BINDIR:-./bin}
|
||||
while getopts "b:dh?x" arg; do
|
||||
case "$arg" in
|
||||
b) BINDIR="$OPTARG" ;;
|
||||
d) log_set_priority 10 ;;
|
||||
h | \?) usage "$0" ;;
|
||||
x) set -x ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
TAG=$1
|
||||
}
|
||||
# this function wraps all the destructive operations
|
||||
# if a curl|bash cuts off the end of the script due to
|
||||
# network, either nothing will happen or will syntax error
|
||||
# out preventing half-done work
|
||||
execute() {
|
||||
tmpdir=$(mktemp -d)
|
||||
log_debug "downloading files into ${tmpdir}"
|
||||
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
|
||||
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
|
||||
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
|
||||
srcdir="${tmpdir}"
|
||||
(cd "${tmpdir}" && untar "${TARBALL}")
|
||||
test ! -d "${BINDIR}" && install -d "${BINDIR}"
|
||||
for binexe in $BINARIES; do
|
||||
if [ "$OS" = "windows" ]; then
|
||||
binexe="${binexe}.exe"
|
||||
fi
|
||||
install "${srcdir}/${binexe}" "${BINDIR}/"
|
||||
log_info "installed ${BINDIR}/${binexe}"
|
||||
done
|
||||
rm -rf "${tmpdir}"
|
||||
}
|
||||
get_binaries() {
|
||||
case "$PLATFORM" in
|
||||
darwin/386) BINARIES="trivy" ;;
|
||||
darwin/amd64) BINARIES="trivy" ;;
|
||||
darwin/arm64) BINARIES="trivy" ;;
|
||||
darwin/armv7) BINARIES="trivy" ;;
|
||||
freebsd/386) BINARIES="trivy" ;;
|
||||
freebsd/amd64) BINARIES="trivy" ;;
|
||||
freebsd/arm64) BINARIES="trivy" ;;
|
||||
freebsd/armv7) BINARIES="trivy" ;;
|
||||
linux/386) BINARIES="trivy" ;;
|
||||
linux/amd64) BINARIES="trivy" ;;
|
||||
linux/ppc64le) BINARIES="trivy" ;;
|
||||
linux/arm64) BINARIES="trivy" ;;
|
||||
linux/armv7) BINARIES="trivy" ;;
|
||||
openbsd/386) BINARIES="trivy" ;;
|
||||
openbsd/amd64) BINARIES="trivy" ;;
|
||||
openbsd/arm64) BINARIES="trivy" ;;
|
||||
openbsd/armv7) BINARIES="trivy" ;;
|
||||
*)
|
||||
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
tag_to_version() {
|
||||
if [ -z "${TAG}" ]; then
|
||||
log_info "checking GitHub for latest tag"
|
||||
else
|
||||
log_info "checking GitHub for tag '${TAG}'"
|
||||
fi
|
||||
REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
|
||||
if test -z "$REALTAG"; then
|
||||
log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
|
||||
exit 1
|
||||
fi
|
||||
# if version starts with 'v', remove it
|
||||
TAG="$REALTAG"
|
||||
VERSION=${TAG#v}
|
||||
}
|
||||
adjust_format() {
|
||||
# change format (tar.gz or zip) based on OS
|
||||
true
|
||||
}
|
||||
adjust_os() {
|
||||
# adjust archive name based on OS
|
||||
case ${OS} in
|
||||
386) OS=32bit ;;
|
||||
amd64) OS=64bit ;;
|
||||
arm) OS=ARM ;;
|
||||
arm64) OS=ARM64 ;;
|
||||
ppc64le) OS=PPC64LE ;;
|
||||
darwin) OS=macOS ;;
|
||||
dragonfly) OS=DragonFlyBSD ;;
|
||||
freebsd) OS=FreeBSD ;;
|
||||
linux) OS=Linux ;;
|
||||
netbsd) OS=NetBSD ;;
|
||||
openbsd) OS=OpenBSD ;;
|
||||
esac
|
||||
true
|
||||
}
|
||||
adjust_arch() {
|
||||
# adjust archive name based on ARCH
|
||||
case ${ARCH} in
|
||||
386) ARCH=32bit ;;
|
||||
amd64) ARCH=64bit ;;
|
||||
arm) ARCH=ARM ;;
|
||||
arm64) ARCH=ARM64 ;;
|
||||
ppc64le) OS=PPC64LE ;;
|
||||
darwin) ARCH=macOS ;;
|
||||
dragonfly) ARCH=DragonFlyBSD ;;
|
||||
freebsd) ARCH=FreeBSD ;;
|
||||
linux) ARCH=Linux ;;
|
||||
netbsd) ARCH=NetBSD ;;
|
||||
openbsd) ARCH=OpenBSD ;;
|
||||
esac
|
||||
true
|
||||
}
|
||||
|
||||
cat /dev/null <<EOF
|
||||
------------------------------------------------------------------------
|
||||
https://github.com/client9/shlib - portable posix shell functions
|
||||
Public domain - http://unlicense.org
|
||||
https://github.com/client9/shlib/blob/master/LICENSE.md
|
||||
but credit (and pull requests) appreciated.
|
||||
------------------------------------------------------------------------
|
||||
EOF
|
||||
is_command() {
|
||||
command -v "$1" >/dev/null
|
||||
}
|
||||
echoerr() {
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
log_prefix() {
|
||||
echo "$0"
|
||||
}
|
||||
_logp=6
|
||||
log_set_priority() {
|
||||
_logp="$1"
|
||||
}
|
||||
log_priority() {
|
||||
if test -z "$1"; then
|
||||
echo "$_logp"
|
||||
return
|
||||
fi
|
||||
[ "$1" -le "$_logp" ]
|
||||
}
|
||||
log_tag() {
|
||||
case $1 in
|
||||
0) echo "emerg" ;;
|
||||
1) echo "alert" ;;
|
||||
2) echo "crit" ;;
|
||||
3) echo "err" ;;
|
||||
4) echo "warning" ;;
|
||||
5) echo "notice" ;;
|
||||
6) echo "info" ;;
|
||||
7) echo "debug" ;;
|
||||
*) echo "$1" ;;
|
||||
esac
|
||||
}
|
||||
log_debug() {
|
||||
log_priority 7 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
|
||||
}
|
||||
log_info() {
|
||||
log_priority 6 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
|
||||
}
|
||||
log_err() {
|
||||
log_priority 3 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
|
||||
}
|
||||
log_crit() {
|
||||
log_priority 2 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
|
||||
}
|
||||
uname_os() {
|
||||
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
case "$os" in
|
||||
cygwin_nt*) os="windows" ;;
|
||||
mingw*) os="windows" ;;
|
||||
msys_nt*) os="windows" ;;
|
||||
esac
|
||||
echo "$os"
|
||||
}
|
||||
uname_arch() {
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
x86_64) arch="amd64" ;;
|
||||
x86) arch="386" ;;
|
||||
i686) arch="386" ;;
|
||||
i386) arch="386" ;;
|
||||
ppc64le) arch="ppc64le" ;;
|
||||
aarch64) arch="arm64" ;;
|
||||
armv5*) arch="armv5" ;;
|
||||
armv6*) arch="armv6" ;;
|
||||
armv7*) arch="armv7" ;;
|
||||
esac
|
||||
echo ${arch}
|
||||
}
|
||||
uname_os_check() {
|
||||
os=$(uname_os)
|
||||
case "$os" in
|
||||
darwin) return 0 ;;
|
||||
dragonfly) return 0 ;;
|
||||
freebsd) return 0 ;;
|
||||
linux) return 0 ;;
|
||||
android) return 0 ;;
|
||||
nacl) return 0 ;;
|
||||
netbsd) return 0 ;;
|
||||
openbsd) return 0 ;;
|
||||
plan9) return 0 ;;
|
||||
solaris) return 0 ;;
|
||||
windows) return 0 ;;
|
||||
esac
|
||||
log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
|
||||
return 1
|
||||
}
|
||||
uname_arch_check() {
|
||||
arch=$(uname_arch)
|
||||
case "$arch" in
|
||||
386) return 0 ;;
|
||||
amd64) return 0 ;;
|
||||
arm64) return 0 ;;
|
||||
armv5) return 0 ;;
|
||||
armv6) return 0 ;;
|
||||
armv7) return 0 ;;
|
||||
ppc64) return 0 ;;
|
||||
ppc64le) return 0 ;;
|
||||
mips) return 0 ;;
|
||||
mipsle) return 0 ;;
|
||||
mips64) return 0 ;;
|
||||
mips64le) return 0 ;;
|
||||
s390x) return 0 ;;
|
||||
amd64p32) return 0 ;;
|
||||
esac
|
||||
log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
|
||||
return 1
|
||||
}
|
||||
untar() {
|
||||
tarball=$1
|
||||
case "${tarball}" in
|
||||
*.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;;
|
||||
*.tar) tar --no-same-owner -xf "${tarball}" ;;
|
||||
*.zip) unzip "${tarball}" ;;
|
||||
*)
|
||||
log_err "untar unknown archive format for ${tarball}"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
http_download_curl() {
|
||||
local_file=$1
|
||||
source_url=$2
|
||||
header=$3
|
||||
if [ -z "$header" ]; then
|
||||
code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
|
||||
else
|
||||
code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
|
||||
fi
|
||||
if [ "$code" != "200" ]; then
|
||||
log_debug "http_download_curl received HTTP status $code"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
http_download_wget() {
|
||||
local_file=$1
|
||||
source_url=$2
|
||||
header=$3
|
||||
if [ -z "$header" ]; then
|
||||
wget -q -O "$local_file" "$source_url"
|
||||
else
|
||||
wget -q --header "$header" -O "$local_file" "$source_url"
|
||||
fi
|
||||
}
|
||||
http_download() {
|
||||
log_debug "http_download $2"
|
||||
if is_command curl; then
|
||||
http_download_curl "$@"
|
||||
return
|
||||
elif is_command wget; then
|
||||
http_download_wget "$@"
|
||||
return
|
||||
fi
|
||||
log_crit "http_download unable to find wget or curl"
|
||||
return 1
|
||||
}
|
||||
http_copy() {
|
||||
tmp=$(mktemp)
|
||||
http_download "${tmp}" "$1" "$2" || return 1
|
||||
body=$(cat "$tmp")
|
||||
rm -f "${tmp}"
|
||||
echo "$body"
|
||||
}
|
||||
github_release() {
|
||||
owner_repo=$1
|
||||
version=$2
|
||||
test -z "$version" && version="latest"
|
||||
giturl="https://github.com/${owner_repo}/releases/${version}"
|
||||
json=$(http_copy "$giturl" "Accept:application/json")
|
||||
test -z "$json" && return 1
|
||||
version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
|
||||
test -z "$version" && return 1
|
||||
echo "$version"
|
||||
}
|
||||
hash_sha256() {
|
||||
TARGET=${1:-/dev/stdin}
|
||||
if is_command gsha256sum; then
|
||||
hash=$(gsha256sum "$TARGET") || return 1
|
||||
echo "$hash" | cut -d ' ' -f 1
|
||||
elif is_command sha256sum; then
|
||||
hash=$(sha256sum "$TARGET") || return 1
|
||||
echo "$hash" | cut -d ' ' -f 1
|
||||
elif is_command shasum; then
|
||||
hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
|
||||
echo "$hash" | cut -d ' ' -f 1
|
||||
elif is_command openssl; then
|
||||
hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
|
||||
echo "$hash" | cut -d ' ' -f a
|
||||
else
|
||||
log_crit "hash_sha256 unable to find command to compute sha-256 hash"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
hash_sha256_verify() {
|
||||
TARGET=$1
|
||||
checksums=$2
|
||||
if [ -z "$checksums" ]; then
|
||||
log_err "hash_sha256_verify checksum file not specified in arg2"
|
||||
return 1
|
||||
fi
|
||||
BASENAME=${TARGET##*/}
|
||||
want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
|
||||
if [ -z "$want" ]; then
|
||||
log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
|
||||
return 1
|
||||
fi
|
||||
got=$(hash_sha256 "$TARGET")
|
||||
if [ "$want" != "$got" ]; then
|
||||
log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
cat /dev/null <<EOF
|
||||
------------------------------------------------------------------------
|
||||
End of functions from https://github.com/client9/shlib
|
||||
------------------------------------------------------------------------
|
||||
EOF
|
||||
|
||||
PROJECT_NAME="trivy"
|
||||
OWNER=aquasecurity
|
||||
REPO="trivy"
|
||||
BINARY=trivy
|
||||
FORMAT=tar.gz
|
||||
OS=$(uname_os)
|
||||
ARCH=$(uname_arch)
|
||||
PREFIX="$OWNER/$REPO"
|
||||
|
||||
# use in logging routines
|
||||
log_prefix() {
|
||||
echo "$PREFIX"
|
||||
}
|
||||
PLATFORM="${OS}/${ARCH}"
|
||||
GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
|
||||
|
||||
uname_os_check "$OS"
|
||||
uname_arch_check "$ARCH"
|
||||
|
||||
parse_args "$@"
|
||||
|
||||
get_binaries
|
||||
|
||||
tag_to_version
|
||||
|
||||
adjust_format
|
||||
|
||||
adjust_os
|
||||
|
||||
adjust_arch
|
||||
|
||||
log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
|
||||
|
||||
NAME=${PROJECT_NAME}_${VERSION}_${OS}-${ARCH}
|
||||
TARBALL=${NAME}.${FORMAT}
|
||||
TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}
|
||||
CHECKSUM=${PROJECT_NAME}_${VERSION}_checksums.txt
|
||||
CHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}
|
||||
|
||||
|
||||
execute
|
||||
18
contrib/junit.tpl
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" ?>
|
||||
<testsuites>
|
||||
{{- range . -}}
|
||||
{{- $failures := len .Vulnerabilities }}
|
||||
<testsuite tests="{{ $failures }}" failures="{{ $failures }}" name="{{ .Target }}" errors="0" skipped="0" time="">
|
||||
{{- if not (eq .Type "") }}
|
||||
<properties>
|
||||
<property name="type" value="{{ .Type }}"></property>
|
||||
</properties>
|
||||
{{- end -}}
|
||||
{{ range .Vulnerabilities }}
|
||||
<testcase classname="{{ .PkgName }}-{{ .InstalledVersion }}" name="[{{ .Vulnerability.Severity }}] {{ .VulnerabilityID }}" time="">
|
||||
<failure message="{{ escapeXML .Title }}" type="description">{{ escapeXML .Description }}</failure>
|
||||
</testcase>
|
||||
{{- end }}
|
||||
</testsuite>
|
||||
{{- end }}
|
||||
</testsuites>
|
||||
95
contrib/sarif.tpl
Normal file
@@ -0,0 +1,95 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
|
||||
"version": "2.1.0",
|
||||
"runs": [
|
||||
{
|
||||
"tool": {
|
||||
"driver": {
|
||||
"name": "Trivy",
|
||||
"informationUri": "https://github.com/aquasecurity/trivy",
|
||||
"fullName": "Trivy Vulnerability Scanner",
|
||||
"version": "0.15.0",
|
||||
"rules": [
|
||||
{{- $t_first := true }}
|
||||
{{- range $result := . }}
|
||||
{{- $vulnerabilityType := .Type }}
|
||||
{{- range .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{ else -}}
|
||||
,
|
||||
{{- end }}
|
||||
{
|
||||
"id": {{ printf "%s: %s-%s %s" $result.Target .PkgName .InstalledVersion .VulnerabilityID | toJson }},
|
||||
"name": "{{ toSarifRuleName $vulnerabilityType }}",
|
||||
"shortDescription": {
|
||||
"text": {{ printf "%v Package: %v" .VulnerabilityID .PkgName | printf "%q" }}
|
||||
},
|
||||
"fullDescription": {
|
||||
"text": {{ endWithPeriod (escapeString .Title) | printf "%q" }}
|
||||
},
|
||||
"defaultConfiguration": {
|
||||
"level": "{{ toSarifErrorLevel .Vulnerability.Severity }}"
|
||||
}
|
||||
{{- with $help_uri := .PrimaryURL -}}
|
||||
,
|
||||
{{ $help_uri | printf "\"helpUri\": %q," -}}
|
||||
{{- else -}}
|
||||
,
|
||||
{{- end }}
|
||||
"help": {
|
||||
"text": {{ printf "Vulnerability %v\nSeverity: %v\nPackage: %v\nInstalled Version: %v\nFixed Version: %v\nLink: [%v](%v)" .VulnerabilityID .Vulnerability.Severity .PkgName .InstalledVersion .FixedVersion .VulnerabilityID .PrimaryURL | printf "%q"}},
|
||||
"markdown": {{ printf "**Vulnerability %v**\n| Severity | Package | Installed Version | Fixed Version | Link |\n| --- | --- | --- | --- | --- |\n|%v|%v|%v|%v|[%v](%v)|\n" .VulnerabilityID .Vulnerability.Severity .PkgName .InstalledVersion .FixedVersion .VulnerabilityID .PrimaryURL | printf "%q"}}
|
||||
},
|
||||
"properties": {
|
||||
"tags": [
|
||||
"vulnerability",
|
||||
"{{ .Vulnerability.Severity }}",
|
||||
{{ .PkgName | printf "%q" }}
|
||||
],
|
||||
"precision": "very-high"
|
||||
}
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"results": [
|
||||
{{- $t_first := true }}
|
||||
{{- range $result := . }}
|
||||
{{- $filePath := .Target }}
|
||||
{{- range $index, $vulnerability := .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{ else -}}
|
||||
,
|
||||
{{- end }}
|
||||
{
|
||||
"ruleId": {{ printf "%s: %s-%s %s" $result.Target .PkgName .InstalledVersion .VulnerabilityID | toJson }},
|
||||
"ruleIndex": {{ $index }},
|
||||
"level": "{{ toSarifErrorLevel $vulnerability.Vulnerability.Severity }}",
|
||||
"message": {
|
||||
"text": {{ endWithPeriod (escapeString $vulnerability.Description) | printf "%q" }}
|
||||
},
|
||||
"locations": [{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "{{ toPathUri $filePath }}",
|
||||
"uriBaseId": "ROOTPATH"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
],
|
||||
"columnKind": "utf16CodeUnits",
|
||||
"originalUriBaseIds": {
|
||||
"ROOTPATH": {
|
||||
"uri": "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
57
docs/advanced/air-gap.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Air-Gapped Environment
|
||||
|
||||
Trivy can be used in air-gapped environments.
|
||||
|
||||
## Download the vulnerability database
|
||||
At first, you need to download the vulnerability database for use in air-gapped environments.
|
||||
Go to [trivy-db][trivy-db] and download `trivy-offline.db.tgz` in the latest release.
|
||||
If you download `trivy-light-offline.db.tgz`, you have to run Trivy with `--light` option.
|
||||
|
||||
```
|
||||
$ wget https://github.com/aquasecurity/trivy-db/releases/latest/download/trivy-offline.db.tgz
|
||||
```
|
||||
|
||||
## Transfer the DB file into the air-gapped environment
|
||||
The way of transfer depends on the environment.
|
||||
|
||||
```
|
||||
$ rsync -av -e ssh /path/to/trivy-offline.db.tgz [user]@[host]:dst
|
||||
```
|
||||
|
||||
## Put the DB file in Trivy's cache directory
|
||||
You have to know where to put the DB file. 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
|
||||
$ mv /path/to/trivy-offline.db.tgz .
|
||||
```
|
||||
|
||||
Then, decompress it.
|
||||
`trivy-offline.db.tgz` file includes two files, `trivy.db` and `metadata.json`.
|
||||
|
||||
```
|
||||
$ tar xvf trivy-offline.db.tgz
|
||||
x trivy.db
|
||||
x metadata.json
|
||||
$ rm trivy-offline.db.tgz
|
||||
```
|
||||
|
||||
In an air-gapped environment it is your responsibility to update the Trivy database on a regular basis, so that the scanner can detect recently-identified vulnerabilities.
|
||||
|
||||
## Run Trivy with --skip-update option
|
||||
In an air-gapped environment, specify `--skip-update` so that Trivy doesn't attempt to download the latest database file.
|
||||
|
||||
```
|
||||
$ trivy image --skip-update alpine:3.12
|
||||
```
|
||||
|
||||
[trivy-db]: https://github.com/aquasecurity/trivy-db/releases
|
||||
28
docs/advanced/container/embed-in-dockerfile.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# 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][microscanner].
|
||||
|
||||
```bash
|
||||
$ 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.
|
||||
```bash
|
||||
[...]
|
||||
# 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 /
|
||||
[...]
|
||||
```
|
||||
|
||||
[microscanner]: https://github.com/aquasecurity/microscanner
|
||||
17
docs/advanced/container/oci.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# OCI Image Layout
|
||||
|
||||
An image directory compliant with [Open Container Image Layout Specification](https://github.com/opencontainers/image-spec/blob/master/spec.md).
|
||||
|
||||
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
|
||||
```
|
||||
28
docs/advanced/container/podman.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Podman
|
||||
|
||||
!!! warning "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][sock].
|
||||
|
||||
|
||||
```bash
|
||||
$ systemctl --user enable --now podman.socket
|
||||
```
|
||||
|
||||
Then, you can scan your image in Podman.
|
||||
|
||||
```bash
|
||||
$ 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
|
||||
```
|
||||
|
||||
[sock]: https://github.com/containers/podman/blob/master/docs/tutorials/remote_client.md#enable-the-podman-service-on-the-server-machine
|
||||
116
docs/advanced/container/unpacked-filesystem.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Unpacked Filesystem
|
||||
|
||||
Scan aan unpacked container image filesystem.
|
||||
|
||||
In this case, Trivy works the same way when scanning containers
|
||||
|
||||
```bash
|
||||
$ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
|
||||
$ trivy rootfs /tmp/rootfs
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```bash
|
||||
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 | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
78
docs/advanced/contrib/help-wanted.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Overview
|
||||
|
||||
We use two labels [help wanted](#help-wanted) and [good first
|
||||
issue](#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!
|
||||
|
||||
195
docs/advanced/contrib/triage.md
Normal file
@@ -0,0 +1,195 @@
|
||||
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
|
||||
1. Responsiveness when explicitly requested information was provided
|
||||
|
||||
It covers:
|
||||
|
||||
1. Issues without a `kind/` or `triage/` label
|
||||
1. Issues without a `priority/` label
|
||||
1. `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’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
|
||||
1. Reviewing and closing PR’s
|
||||
1. Closing stale issues
|
||||
|
||||
|
||||
## 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
|
||||
1. Reprioritizing bugs that have not been resolved by the release
|
||||
1. Letting users know if we believe that there is still an issue
|
||||
|
||||
This includes reviewing:
|
||||
|
||||
1. Every issue that hasn’t been touched in the last 2 days
|
||||
1. Re-evaluation of long-term issues
|
||||
1. Re-evaluation of short-term issues
|
||||
|
||||
|
||||
## 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 <x> 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 <reason>. 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](https://github.com/aquasecurity/trivy/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
and [good first issue](https://github.com/aquasecurity/trivy/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
to identify issues that have been specially groomed for new contributors.
|
||||
|
||||
We have specific [guidelines](/docs/advanced/contribd/contrib/help-wanted.md)
|
||||
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.
|
||||
2
docs/advanced/index.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Advanced
|
||||
This section describes advanced features, integrations, etc.
|
||||
4
docs/advanced/integrations/aws-codepipeline.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# AWS CodePipeline
|
||||
See [this blog post][blog] for an example of using Trivy within AWS CodePipeline.
|
||||
|
||||
[blog]: https://aws.amazon.com/blogs/containers/scanning-images-with-trivy-in-an-aws-codepipeline/
|
||||
29
docs/advanced/integrations/aws-security-hub.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# AWS Security Hub
|
||||
|
||||
## Upload findings to Security Hub
|
||||
|
||||
In the following example using the template `asff.tpl`, [ASFF](https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format.html) 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.
|
||||
|
||||
Then, you can upload it with AWS CLI.
|
||||
|
||||
```
|
||||
$ aws securityhub batch-import-findings --findings file://report.asff
|
||||
```
|
||||
|
||||
## Customize
|
||||
You can customize [asff.tpl](https://github.com/aquasecurity/trivy/blob/main/contrib/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
|
||||
https://aws.amazon.com/blogs/security/how-to-build-ci-cd-pipeline-container-vulnerability-scanning-trivy-and-aws-security-hub/
|
||||
34
docs/advanced/integrations/circleci.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 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 --exit-code 0 --no-progress trivy-ci-test:${CIRCLE_SHA1}
|
||||
workflows:
|
||||
version: 2
|
||||
release:
|
||||
jobs:
|
||||
- build
|
||||
```
|
||||
|
||||
[Example][example]
|
||||
[Repository][repository]
|
||||
|
||||
[example]: https://circleci.com/gh/aquasecurity/trivy-ci-test
|
||||
[repository]: https://github.com/aquasecurity/trivy-ci-test
|
||||
9
docs/advanced/integrations/github-actions.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# GitHub Actions
|
||||
|
||||
- Here is the [Trivy Github Action][action]
|
||||
- The Microsoft Azure team have written a [container-scan action][azure] that uses Trivy and Dockle
|
||||
- For full control over the options specified to Trivy, this [blog post][blog] describes adding Trivy into your own GitHub action workflows
|
||||
|
||||
[action]: https://github.com/aquasecurity/trivy-action
|
||||
[azure]: https://github.com/Azure/container-scan
|
||||
[blog]: https://blog.aquasec.com/devsecops-with-trivy-github-actions
|
||||
157
docs/advanced/integrations/gitlab-ci.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# GitLab CI
|
||||
|
||||
If you're a GitLab Ultimate customer, GitLab 14.0 and above include out-of-the-box integration with Trivy. To enable it for your project, simply add the container scanning template to your `.gitlab-ci.yml` file. For more details, please refer to [GitLab's documentation](https://docs.gitlab.com/ee/user/application_security/container_scanning/).
|
||||
|
||||
If you're using an earlier version of GitLab, you can still use the new integration by copying the [contents of the 14.0 template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml) to your configuration.
|
||||
|
||||
Alternatively, you can always use the example configurations below.
|
||||
|
||||
```yaml
|
||||
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
|
||||
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 --exit-code 0 --cache-dir .trivycache/ --no-progress --format template --template "@contrib/gitlab.tpl" -o gl-container-scanning-report.json $IMAGE
|
||||
# Print report
|
||||
- ./trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --severity HIGH $IMAGE
|
||||
# Fail on severe vulnerabilities
|
||||
- ./trivy --exit-code 1 --cache-dir .trivycache/ --severity CRITICAL --no-progress $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][example]
|
||||
[Repository][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.
|
||||
|
||||
```yaml
|
||||
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"
|
||||
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 --download-db-only --no-progress --cache-dir .trivycache/
|
||||
# Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there
|
||||
- time trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --format template --template "@/contrib/gitlab.tpl"
|
||||
--output "$CI_PROJECT_DIR/gl-container-scanning-report.json" "$FULL_IMAGE_NAME"
|
||||
# Prints full report
|
||||
- time trivy --exit-code 0 --cache-dir .trivycache/ --no-progress "$FULL_IMAGE_NAME"
|
||||
# Fail on critical vulnerabilities
|
||||
- time trivy --exit-code 1 --cache-dir .trivycache/ --severity CRITICAL --no-progress "$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
|
||||
```
|
||||
|
||||
[example]: https://gitlab.com/aquasecurity/trivy-ci-test/pipelines
|
||||
[repository]: https://github.com/aquasecurity/trivy-ci-test
|
||||
|
||||
### 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](https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html)
|
||||
has been included. The key things to update from the above examples are
|
||||
the `template` and `report` type. An updated example is below.
|
||||
|
||||
```yaml
|
||||
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
|
||||
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 --exit-code 0 --cache-dir .trivycache/ --no-progress --format template --template "@contrib/gitlab-codeclimate.tpl" -o gl-codeclimate.json $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:
|
||||
paths:
|
||||
gl-codeclimate.json
|
||||
reports:
|
||||
codequality: gl-codeclimate.json
|
||||
```
|
||||
|
||||
Currently gitlab only supports a single code quality report. There is an
|
||||
open [feature request](https://gitlab.com/gitlab-org/gitlab/-/issues/9014)
|
||||
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`.
|
||||
4
docs/advanced/integrations/index.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# 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`.
|
||||
|
||||
Since in automated scenarios such as CI/CD you are only interested in the end result, and not the full report, use the `--light` flag to optimize for this scenario and get fast results.
|
||||
29
docs/advanced/integrations/travis-ci.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# 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 --exit-code 0 --severity HIGH --no-progress trivy-ci-test:${COMMIT}
|
||||
- ./trivy --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:${COMMIT}
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/trivy
|
||||
```
|
||||
|
||||
[Example][example]
|
||||
[Repository][repository]
|
||||
|
||||
[example]: https://travis-ci.org/aquasecurity/trivy-ci-test
|
||||
[repository]: https://github.com/aquasecurity/trivy-ci-test
|
||||
59
docs/advanced/modes/client-server.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# 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 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
|
||||
```
|
||||
|
||||
## Client
|
||||
Then, specify the remote address.
|
||||
```
|
||||
$ trivy client --remote http://localhost:8080 alpine:3.10
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
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 | | |
|
||||
+---------+------------------+----------+-------------------+---------------+
|
||||
```
|
||||
</details>
|
||||
|
||||
## Authentication
|
||||
|
||||
```
|
||||
$ trivy server --listen localhost:8080 --token dummy
|
||||
```
|
||||
|
||||
```
|
||||
$ trivy client --remote http://localhost:8080 --token dummy alpine:3.10
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
|
||||
16
docs/advanced/modes/standalone.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Standalone
|
||||
|
||||
`trivy image`, `trivy filesystem`, and `trivy repo` works as standalone mode.
|
||||
|
||||
## Image
|
||||
|
||||

|
||||
|
||||
## Filesystem
|
||||
|
||||

|
||||
|
||||
## Git Repository
|
||||
|
||||

|
||||
|
||||
173
docs/advanced/plugins.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# 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][kubectl], [Helm][helm], and [Conftest][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][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:
|
||||
|
||||
```bash
|
||||
$ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl
|
||||
```
|
||||
## 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`
|
||||
|
||||
```bash
|
||||
$ 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][trivy-plugin-kubectl].
|
||||
|
||||
If you want to omit even the subcommand, you can use `TRIVY_RUN_AS_PLUGIN` environment variable.
|
||||
|
||||
```bash
|
||||
$ 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.
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
```bash
|
||||
$ trivy plugin uninstall kubectl
|
||||
```
|
||||
|
||||
## Building Plugins
|
||||
Each plugin has a top-level directory, and then a plugin.yaml file.
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
```yaml
|
||||
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.
|
||||
|
||||
## Example
|
||||
https://github.com/aquasecurity/trivy-plugin-kubectl
|
||||
|
||||
[kubectl]: https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/
|
||||
[helm]: https://helm.sh/docs/topics/plugins/
|
||||
[conftest]: https://www.conftest.dev/plugins/
|
||||
[go-getter]: https://github.com/hashicorp/go-getter
|
||||
[trivy-plugin-kubectl]: https://github.com/aquasecurity/trivy-plugin-kubectl
|
||||
|
||||
7
docs/advanced/private-registries/docker-hub.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Docker Hub needs `TRIVY_USERNAME` and `TRIVY_PASSWORD`.
|
||||
You don't need to set ENV vars when download from public repository.
|
||||
|
||||
```bash
|
||||
export TRIVY_USERNAME={DOCKERHUB_USERNAME}
|
||||
export TRIVY_PASSWORD={DOCKERHUB_PASSWORD}
|
||||
```
|
||||
4
docs/advanced/private-registries/ecr.md
Normal file
@@ -0,0 +1,4 @@
|
||||
Trivy uses AWS SDK. You don't need to install `aws` CLI tool.
|
||||
You can use [AWS CLI's ENV Vars][env-var].
|
||||
|
||||
[env-var]: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
|
||||
7
docs/advanced/private-registries/gcr.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Trivy uses Google Cloud SDK. You don't need to install `gcloud` command.
|
||||
|
||||
If you want to use target project's repository, you can settle via `GOOGLE_APPLICATION_CREDENTIAL`.
|
||||
```bash
|
||||
# must set TRIVY_USERNAME empty char
|
||||
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential.json
|
||||
```
|
||||
4
docs/advanced/private-registries/index.md
Normal file
@@ -0,0 +1,4 @@
|
||||
Trivy can download images from a private registry, without installing `Docker` or any other 3rd party tools.
|
||||
That's because it's easy to run in a CI process.
|
||||
|
||||
All you have to do is install `Trivy` and set ENV vars.
|
||||
9
docs/advanced/private-registries/self.md
Normal file
@@ -0,0 +1,9 @@
|
||||
BasicAuth server needs `TRIVY_USERNAME` and `TRIVY_PASSWORD`.
|
||||
|
||||
```bash
|
||||
export TRIVY_USERNAME={USERNAME}
|
||||
export TRIVY_PASSWORD={PASSWORD}
|
||||
|
||||
# if you want to use 80 port, use NonSSL
|
||||
export TRIVY_NON_SSL=true
|
||||
```
|
||||
9
docs/build/Dockerfile
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
FROM squidfunk/mkdocs-material:7.0.6
|
||||
|
||||
## 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
|
||||
|
||||
RUN pip install mike mkdocs-macros-plugin
|
||||
30
docs/getting-started/cli/client.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Client
|
||||
|
||||
```bash
|
||||
NAME:
|
||||
trivy client - client mode
|
||||
|
||||
USAGE:
|
||||
trivy client [command options] image_name
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--input value, -i value input file path instead of image name [$TRIVY_INPUT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
|
||||
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine) (default: false) [$TRIVY_REMOVED_PKGS]
|
||||
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--token value for authentication [$TRIVY_TOKEN]
|
||||
--token-header value specify a header name for token (default: "Trivy-Token") [$TRIVY_TOKEN_HEADER]
|
||||
--remote value server address (default: "http://localhost:4954") [$TRIVY_REMOTE]
|
||||
--custom-headers value custom headers [$TRIVY_CUSTOM_HEADERS]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
29
docs/getting-started/cli/config.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Config
|
||||
|
||||
``` bash
|
||||
NAME:
|
||||
trivy config - scan config files
|
||||
|
||||
USAGE:
|
||||
trivy config [command options] dir
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
|
||||
--reset remove all caches and database (default: false) [$TRIVY_RESET]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--skip-files value specify the file paths to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directories where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--policy value, --config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_POLICY]
|
||||
--data value, --config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_DATA]
|
||||
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES]
|
||||
--file-patterns value specify file patterns [$TRIVY_FILE_PATTERNS]
|
||||
--include-successes include successes of misconfigurations (default: false) [$TRIVY_INCLUDE_SUCCESSES]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
34
docs/getting-started/cli/fs.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Filesystem
|
||||
|
||||
```bash
|
||||
NAME:
|
||||
trivy filesystem - scan local filesystem
|
||||
|
||||
USAGE:
|
||||
trivy filesystem [command options] dir
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--skip-db-update, --skip-update skip updating vulnerability database (default: false) [$TRIVY_SKIP_UPDATE, $TRIVY_SKIP_DB_UPDATE]
|
||||
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
|
||||
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
|
||||
--security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--skip-files value specify the file paths to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directories where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_CONFIG_POLICY]
|
||||
--config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_CONFIG_DATA]
|
||||
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
34
docs/getting-started/cli/image.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Image
|
||||
|
||||
```bash
|
||||
NAME:
|
||||
trivy image - scan an image
|
||||
|
||||
USAGE:
|
||||
trivy image [command options] image_name
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--input value, -i value input file path instead of image name [$TRIVY_INPUT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--skip-update skip db update (default: false) [$TRIVY_SKIP_UPDATE]
|
||||
--download-db-only download/update vulnerability database but don't run a scan (default: false) [$TRIVY_DOWNLOAD_DB_ONLY]
|
||||
--reset remove all caches and database (default: false) [$TRIVY_RESET]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
|
||||
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
|
||||
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine) (default: false) [$TRIVY_REMOVED_PKGS]
|
||||
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--light light mode: it's faster, but vulnerability descriptions and references are not displayed (default: false) [$TRIVY_LIGHT]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--skip-files value specify the file path to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directory where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
30
docs/getting-started/cli/index.md
Normal file
@@ -0,0 +1,30 @@
|
||||
Trivy has several sub commands, image, fs, repo, client and server.
|
||||
|
||||
``` bash
|
||||
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
|
||||
config, conf scan config files
|
||||
plugin, p manage plugins
|
||||
help, h Shows a list of commands or help for one command
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
--quiet, -q suppress progress bar and log output (default: false) [$TRIVY_QUIET]
|
||||
--debug, -d debug mode (default: false) [$TRIVY_DEBUG]
|
||||
--cache-dir value cache directory (default: "/Users/teppei/Library/Caches/trivy") [$TRIVY_CACHE_DIR]
|
||||
--help, -h show help (default: false)
|
||||
--version, -v print the version (default: false)
|
||||
|
||||
```
|
||||
31
docs/getting-started/cli/repo.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Repository
|
||||
|
||||
```bash
|
||||
NAME:
|
||||
trivy repository - scan remote repository
|
||||
|
||||
USAGE:
|
||||
trivy repository [command options] repo_url
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--input value, -i value input file path instead of image name [$TRIVY_INPUT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--skip-update skip db update (default: false) [$TRIVY_SKIP_UPDATE]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
|
||||
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine) (default: false) [$TRIVY_REMOVED_PKGS]
|
||||
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--skip-files value specify the file path to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directory where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
34
docs/getting-started/cli/rootfs.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Rootfs
|
||||
|
||||
```bash
|
||||
NAME:
|
||||
trivy rootfs - scan rootfs
|
||||
|
||||
USAGE:
|
||||
trivy rootfs [command options] dir
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--skip-db-update, --skip-update skip updating vulnerability database (default: false) [$TRIVY_SKIP_UPDATE, $TRIVY_SKIP_DB_UPDATE]
|
||||
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
|
||||
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
|
||||
--security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--skip-files value specify the file paths to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directories where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_CONFIG_POLICY]
|
||||
--config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_CONFIG_DATA]
|
||||
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
19
docs/getting-started/cli/server.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Server
|
||||
|
||||
```bash
|
||||
NAME:
|
||||
trivy server - server mode
|
||||
|
||||
USAGE:
|
||||
trivy server [command options] [arguments...]
|
||||
|
||||
OPTIONS:
|
||||
--skip-update skip db update (default: false) [$TRIVY_SKIP_UPDATE]
|
||||
--download-db-only download/update vulnerability database but don't run a scan (default: false) [$TRIVY_DOWNLOAD_DB_ONLY]
|
||||
--reset remove all caches and database (default: false) [$TRIVY_RESET]
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
--token value for authentication [$TRIVY_TOKEN]
|
||||
--token-header value specify a header name for token (default: "Trivy-Token") [$TRIVY_TOKEN_HEADER]
|
||||
--listen value listen address (default: "localhost:4954") [$TRIVY_LISTEN]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
10
docs/getting-started/credit.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Author
|
||||
|
||||
[Teppei Fukuda][knqyf263] (knqyf263)
|
||||
|
||||
# Contributors
|
||||
|
||||
Thanks to all [contributors][contributors]
|
||||
|
||||
[knqyf263]: https://github.com/knqyf263
|
||||
[contributors]: https://github.com/aquasecurity/trivy/graphs/contributors
|
||||
45
docs/getting-started/further.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Further Reading
|
||||
|
||||
## Presentations
|
||||
- Aqua Security YouTube Channel
|
||||
- [Trivy - container image scanning][intro]
|
||||
- [Using Trivy in client server mode][server]
|
||||
- [Tweaking Trivy output to fit your workflow][tweaking]
|
||||
- [How does a vulnerability scanner identify packages?][identify]
|
||||
- CNCF Webinar 2020
|
||||
- [Trivy Open Source Scanner for Container Images – Just Download and Run!][cncf]
|
||||
- KubeCon + CloudNativeCon Europe 2020 Virtual
|
||||
- [Handling Container Vulnerabilities with Open Policy Agent - Teppei Fukuda, Aqua Security][kubecon]
|
||||
|
||||
## Blogs
|
||||
- [Trivy Vulnerability Scanner Joins the Aqua Open-source Family][join]
|
||||
- [Trivy Image Vulnerability Scanner Now Under Apache 2.0 License][license]
|
||||
- [DevSecOps with Trivy and GitHub Actions][actions]
|
||||
- [Find Image Vulnerabilities Using GitHub and Aqua Security Trivy Action][actions2]
|
||||
- [Using Trivy to Discover Vulnerabilities in VS Code Projects][vscode]
|
||||
|
||||
## External Blogs/Links
|
||||
- [the vulnerability remediation lifecycle of Alpine containers][alpine]
|
||||
- [Open Source CVE Scanner Round-Up: Clair vs Anchore vs Trivy][round-up]
|
||||
- [Docker Image Security: Static Analysis Tool Comparison – Anchore Engine vs Clair vs Trivy][tool-comparison]
|
||||
- [Research Spike: evaluate Trivy for scanning running containers][gitlab]
|
||||
- [Istio evaluates scanners][istio]
|
||||
|
||||
[intro]: https://www.youtube.com/watch?v=AzOBGm7XxOA
|
||||
[cncf]: https://www.youtube.com/watch?v=XnYxX9uueoQ
|
||||
[server]: https://www.youtube.com/watch?v=tNQ-VlahtYM
|
||||
[kubecon]: https://www.youtube.com/watch?v=WKE2XNZ2zr4
|
||||
[identify]: https://www.youtube.com/watch?v=PaMnzeHBa8M
|
||||
[tweaking]: https://www.youtube.com/watch?v=wFIGUjcRLnU
|
||||
|
||||
[join]: https://blog.aquasec.com/trivy-vulnerability-scanner-joins-aqua-family
|
||||
[license]: https://blog.aquasec.com/trivy-open-source-vulnerability-scanner-apache2.0-license
|
||||
[actions]: https://blog.aquasec.com/devsecops-with-trivy-github-actions
|
||||
[actions2]: https://blog.aquasec.com/github-vulnerability-scanner-trivy
|
||||
[vscode]: https://blog.aquasec.com/trivy-open-source-vulnerability-scanner-vs-code
|
||||
|
||||
[alpine]: https://ariadne.space/2021/06/08/the-vulnerability-remediation-lifecycle-of-alpine-containers/
|
||||
[round-up]: https://boxboat.com/2020/04/24/image-scanning-tech-compared/
|
||||
[tool-comparison]: https://www.a10o.net/devsecops/docker-image-security-static-analysis-tool-comparison-anchore-engine-vs-clair-vs-trivy/
|
||||
[gitlab]: https://gitlab.com/gitlab-org/gitlab/-/issues/270888
|
||||
[istio]: https://github.com/istio/release-builder/pull/687#issuecomment-874938417
|
||||
202
docs/getting-started/installation.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# Installation
|
||||
|
||||
## RHEL/CentOS
|
||||
|
||||
|
||||
=== "Repository"
|
||||
Add repository setting to `/etc/yum.repos.d`.
|
||||
|
||||
``` bash
|
||||
$ sudo vim /etc/yum.repos.d/trivy.repo
|
||||
[trivy]
|
||||
name=Trivy repository
|
||||
baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$releasever/$basearch/
|
||||
gpgcheck=0
|
||||
enabled=1
|
||||
$ sudo yum -y update
|
||||
$ sudo yum -y install trivy
|
||||
```
|
||||
|
||||
=== "RPM"
|
||||
|
||||
``` bash
|
||||
rpm -ivh https://github.com/aquasecurity/trivy/releases/download/{{ git.tag }}/trivy_{{ git.tag[1:] }}_Linux-64bit.rpm
|
||||
```
|
||||
|
||||
## Debian/Ubuntu
|
||||
|
||||
=== "Repository"
|
||||
Add repository setting to `/etc/apt/sources.list.d`.
|
||||
|
||||
``` bash
|
||||
sudo apt-get install wget apt-transport-https gnupg lsb-release
|
||||
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
|
||||
echo deb 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
|
||||
```
|
||||
|
||||
=== "DEB"
|
||||
|
||||
``` bash
|
||||
wget https://github.com/aquasecurity/trivy/releases/download/{{ git.tag }}/trivy_{{ git.tag[1:] }}_Linux-64bit.deb
|
||||
sudo dpkg -i trivy_{{ git.tag[1:] }}_Linux-64bit.deb
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Arch Linux
|
||||
Package trivy-bin can be installed from the Arch User Repository.
|
||||
|
||||
=== "pikaur"
|
||||
|
||||
``` bash
|
||||
pikaur -Sy trivy-bin
|
||||
```
|
||||
|
||||
=== "yay"
|
||||
|
||||
``` bash
|
||||
yay -Sy trivy-bin
|
||||
```
|
||||
|
||||
## Homebrew
|
||||
|
||||
You can use homebrew on macOS and Linux.
|
||||
|
||||
```bash
|
||||
brew install aquasecurity/trivy/trivy
|
||||
```
|
||||
|
||||
## Nix/NixOS
|
||||
|
||||
You can use nix on Linux or macOS and on others unofficially.
|
||||
|
||||
Note that trivy is currently only in the unstable channels.
|
||||
|
||||
```bash
|
||||
nix-env --install trivy
|
||||
```
|
||||
|
||||
Or through your configuration on NixOS or with home-manager as usual
|
||||
|
||||
|
||||
## Install Script
|
||||
This script downloads Trivy binary based on your OS and architecture.
|
||||
|
||||
```bash
|
||||
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin {{ git.tag }}
|
||||
```
|
||||
|
||||
## Binary
|
||||
|
||||
Download the archive file for your operating system/architecture from [here](https://github.com/aquasecurity/trivy/releases/tag/{{ git.tag }}).
|
||||
Unpack the archive, and put the binary somewhere in your `$PATH` (on UNIX-y systems, /usr/local/bin or the like).
|
||||
Make sure it has execution bits turned on.
|
||||
|
||||
## From source
|
||||
|
||||
```bash
|
||||
mkdir -p $GOPATH/src/github.com/aquasecurity
|
||||
cd $GOPATH/src/github.com/aquasecurity
|
||||
git clone --depth 1 --branch {{ git.tag }} https://github.com/aquasecurity/trivy
|
||||
cd trivy/cmd/trivy/
|
||||
export GO111MODULE=on
|
||||
go install
|
||||
```
|
||||
|
||||
## Docker
|
||||
### Docker Hub
|
||||
Replace [YOUR_CACHE_DIR] with the cache directory on your machine.
|
||||
|
||||
```bash
|
||||
docker pull aquasec/trivy:{{ git.tag[1:] }}
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
=== "Linux"
|
||||
|
||||
``` bash
|
||||
docker run --rm -v [YOUR_CACHE_DIR]:/root/.cache/ aquasec/trivy:{{ git.tag[1:] }} [YOUR_IMAGE_NAME]
|
||||
```
|
||||
|
||||
=== "macOS"
|
||||
|
||||
``` bash
|
||||
yay -Sy trivy-bin
|
||||
docker run --rm -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy:{{ git.tag[1:] }} python:3.4-alpine
|
||||
```
|
||||
|
||||
If you would like to scan the image on your host machine, you need to mount `docker.sock`.
|
||||
|
||||
```bash
|
||||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v $HOME/Library/Caches:/root/.cache/ aquasec/trivy:{{ git.tag[1:] }} python:3.4-alpine
|
||||
```
|
||||
|
||||
Please re-pull latest `aquasec/trivy` if an error occurred.
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```bash
|
||||
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 |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### GitHub Container Registry
|
||||
|
||||
The same image is hosted on [GitHub Container Registry][registry] as well.
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/aquasecurity/trivy:{{ git.tag[1:] }}
|
||||
```
|
||||
|
||||
|
||||
### Amazon ECR Public
|
||||
|
||||
The same image is hosted on [Amazon ECR Public][ecr] as well.
|
||||
|
||||
```bash
|
||||
docker pull public.ecr.aws/aquasecurity/trivy:{{ git.tag[1:] }}
|
||||
```
|
||||
## Helm
|
||||
### Installing from the the Aqua Chart Repository
|
||||
|
||||
```
|
||||
helm repo add aquasecurity https://aquasecurity.github.io/helm-charts/
|
||||
helm repo update
|
||||
helm search repo trivy
|
||||
helm install my-trivy aquasecurity/trivy
|
||||
```
|
||||
|
||||
### Installing the Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```
|
||||
helm install my-release .
|
||||
```
|
||||
|
||||
The command deploys Trivy on the Kubernetes cluster in the default configuration. The [Parameters][helm]
|
||||
section lists the parameters that can be configured during installation.
|
||||
|
||||
> **Tip**: List all releases using `helm list`.
|
||||
|
||||
[ecr]: https://gallery.ecr.aws/aquasecurity/trivy
|
||||
[registry]: https://github.com/orgs/aquasecurity/packages/container/package/trivy
|
||||
[helm]: https://github.com/aquasecurity/trivy/tree/{{ git.tag }}/helm/trivy
|
||||
83
docs/getting-started/overview.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Overview
|
||||
|
||||
Trivy detects two types of security issues:
|
||||
|
||||
- [Vulnerabilities][vuln]
|
||||
- [Misconfigurations][misconf]
|
||||
|
||||
Trivy can scan three different artifacts:
|
||||
|
||||
- [Container Images][container]
|
||||
- [Filesystem][filesystem] and [Rootfs][rootfs]
|
||||
- [Git Repositories][repo]
|
||||
|
||||
Trivy can be run in two different modes:
|
||||
|
||||
- [Standalone][standalone]
|
||||
- [Client/Server][client-server]
|
||||
|
||||
It is designed to be used in CI. Before pushing to a container registry or deploying your application, you can scan your local container image and other artifacts easily.
|
||||
See [Integrations][integrations] for details.
|
||||
|
||||
## Features
|
||||
|
||||
- Comprehensive vulnerability detection
|
||||
- [OS packages][os] (Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
|
||||
- [**Language-specific packages**][lang] (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, Maven, and Go)
|
||||
- Detect IaC misconfigurations
|
||||
- A wide variety of [built-in policies][builtin] are provided **out of the box**:
|
||||
- Kubernetes
|
||||
- Docker
|
||||
- Terraform
|
||||
- more coming soon
|
||||
- Support custom policies
|
||||
- Simple
|
||||
- Specify only an image name, a directory containing IaC configs, or an artifact name
|
||||
- See [Quick Start][quickstart]
|
||||
- Fast
|
||||
- The first scan will finish within 10 seconds (depending on your network). Consequent scans will finish in single seconds.
|
||||
- Unlike other scanners that take long to fetch vulnerability information (~10 minutes) on the first run, and encourage you to maintain a durable vulnerability database, Trivy is stateless and requires no maintenance or preparation.
|
||||
- Easy installation
|
||||
- `apt-get install`, `yum install` and `brew install` is possible (See [Installation](installation.md))
|
||||
- **No pre-requisites** such as installation of DB, libraries, etc.
|
||||
- High accuracy
|
||||
- **Especially Alpine Linux and RHEL/CentOS**
|
||||
- Other OSes are also high
|
||||
- DevSecOps
|
||||
- **Suitable for CI** such as Travis CI, CircleCI, Jenkins, GitLab CI, etc.
|
||||
- See [CI Example][integrations]
|
||||
- Support multiple formats
|
||||
- container image
|
||||
- A local image in Docker Engine which is running as a daemon
|
||||
- A local image in [Podman][podman] (>=2.0) which is exposing a socket
|
||||
- A remote image in Docker Registry such as Docker Hub, ECR, GCR and ACR
|
||||
- A tar archive stored in the `docker save` / `podman save` formatted file
|
||||
- An image directory compliant with [OCI Image Format][oci]
|
||||
- local filesystem and rootfs
|
||||
- remote git repository
|
||||
|
||||
Please see [LICENSE][license] for Trivy licensing information.
|
||||
|
||||
!!! note
|
||||
Trivy uses vulnerability information from a variety of sources, some of which are licensed for non-commercial use only.
|
||||
|
||||
[vuln]: ../vulnerability/scanning/index.md
|
||||
[misconf]: ../misconfiguration/index.md
|
||||
[container]: ../vulnerability/scanning/image.md
|
||||
[rootfs]: ../vulnerability/scanning/rootfs.md
|
||||
[filesystem]: ../vulnerability/scanning/filesystem.md
|
||||
[repo]: ../vulnerability/scanning/git-repository.md
|
||||
|
||||
[standalone]: ../advanced/modes/standalone.md
|
||||
[client-server]: ../advanced/modes/client-server.md
|
||||
[integrations]: ../advanced/integrations/index.md
|
||||
|
||||
[os]: ../vulnerability/detection/os.md
|
||||
[lang]: ../vulnerability/detection/language.md
|
||||
|
||||
[builtin]: ../misconfiguration/policy/builtin.md
|
||||
[quickstart]: quickstart.md
|
||||
[podman]: ../advanced/container/podman.md
|
||||
|
||||
[oci]: https://github.com/opencontainers/image-spec
|
||||
[license]: https://github.com/aquasecurity/trivy/blob/main/LICENSE
|
||||
83
docs/getting-started/quickstart.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Quick Start
|
||||
|
||||
## Scan image for vulnerabilities
|
||||
|
||||
Simply specify an image name (and a tag).
|
||||
|
||||
```
|
||||
$ trivy image [YOUR_IMAGE_NAME]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ trivy image python:3.4-alpine
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
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 |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
For more details, see [here][vulnerability].
|
||||
|
||||
## Scan directory for misconfigurations
|
||||
|
||||
Simply specify a directory containing IaC files such as Terraform and Dockerfile.
|
||||
|
||||
```
|
||||
$ trivy config [YOUR_IAC_DIR]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ ls build/
|
||||
Dockerfile
|
||||
$ trivy config ./build
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2021-07-09T10:06:29.188+0300 INFO Need to update the built-in policies
|
||||
2021-07-09T10:06:29.188+0300 INFO Downloading the built-in policies...
|
||||
2021-07-09T10:06:30.520+0300 INFO Detected config files: 1
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
For more details, see [here][misconf].
|
||||
|
||||
[vulnerability]: ../vulnerability/scanning/index.md
|
||||
[misconf]: ../misconfiguration/index.md
|
||||
109
docs/getting-started/troubleshooting.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Troubleshooting
|
||||
|
||||
## Scan
|
||||
### Timeout
|
||||
|
||||
!!! error
|
||||
``` bash
|
||||
$ 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
|
||||
``` bash
|
||||
$ 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
|
||||
```
|
||||
|
||||
### 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][boltdb].
|
||||
|
||||
[boltdb]: https://github.com/boltdb/bolt#opening-a-database
|
||||
|
||||
### Error downloading vulnerability DB
|
||||
|
||||
!!! error
|
||||
FATAL failed to download vulnerability DB
|
||||
|
||||
If trivy is running behind corporate firewall try to whitelist urls below:
|
||||
|
||||
- api.github.com
|
||||
- github.com
|
||||
- github-releases.githubusercontent.com
|
||||
|
||||
## 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
|
||||
```
|
||||
BIN
docs/imgs/client-server.png
Normal file
|
After Width: | Height: | Size: 278 KiB |
1151
docs/imgs/excalidraw/client-server.excalidraw
Normal file
397
docs/imgs/excalidraw/fs.excalidraw
Normal file
@@ -0,0 +1,397 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
504
docs/imgs/excalidraw/image.excalidraw
Normal file
@@ -0,0 +1,504 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
352
docs/imgs/excalidraw/misconf.excalidraw
Normal file
@@ -0,0 +1,352 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
"elements": [
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 573,
|
||||
"versionNonce": 2034670720,
|
||||
"isDeleted": false,
|
||||
"id": "BkXuq_6BxgqZGZWc8oCtu",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 599.211669921875,
|
||||
"y": 376.32061767578125,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fd7e14",
|
||||
"width": 867.8921508789062,
|
||||
"height": 151.39703369140625,
|
||||
"seed": 1632394695,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 572,
|
||||
"versionNonce": 425683840,
|
||||
"isDeleted": false,
|
||||
"id": "YQURTHNPSe05RPSlYRcok",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 983.89404296875,
|
||||
"y": 399.98724365234375,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 88,
|
||||
"height": 45,
|
||||
"seed": 891391049,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 36,
|
||||
"fontFamily": 1,
|
||||
"text": "Trivy",
|
||||
"baseline": 32,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 822,
|
||||
"versionNonce": 1061096576,
|
||||
"isDeleted": false,
|
||||
"id": "6dpF2EyZBtYgO6MrvGj0-",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 771.2554931640625,
|
||||
"y": 469.7777099609375,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 507,
|
||||
"height": 35,
|
||||
"seed": 687997545,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability/Misconfiguration Scanner",
|
||||
"baseline": 25,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 763,
|
||||
"versionNonce": 560331648,
|
||||
"isDeleted": false,
|
||||
"id": "cpnTMy7L2AUg9IDJppF4H",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 602.28369140625,
|
||||
"y": 258.8445587158203,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fab005",
|
||||
"width": 397.493408203125,
|
||||
"height": 103.28388977050778,
|
||||
"seed": 77164935,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 1072,
|
||||
"versionNonce": 212434048,
|
||||
"isDeleted": false,
|
||||
"id": "9-blmNVtLesthMSY_f60t",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 630.9301147460938,
|
||||
"y": 292.4002990722656,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 331,
|
||||
"height": 35,
|
||||
"seed": 860091815,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Infrastructure as Code",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1194,
|
||||
"versionNonce": 131337088,
|
||||
"isDeleted": false,
|
||||
"id": "gugZxhi7ThlcjWY_MFO7q",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1021.5928955078125,
|
||||
"y": 261.56090545654297,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#be4bdb",
|
||||
"width": 441.0702514648438,
|
||||
"height": 99.05134582519533,
|
||||
"seed": 1232790121,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 1270,
|
||||
"versionNonce": 591785088,
|
||||
"isDeleted": false,
|
||||
"id": "K48gtpesBxIGJxLTnI2CB",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1173.3179931640625,
|
||||
"y": 294.12510681152344,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 137,
|
||||
"height": 35,
|
||||
"seed": 449264361,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Filesystem",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1319,
|
||||
"versionNonce": 1264839808,
|
||||
"isDeleted": false,
|
||||
"id": "BYJwfkhd1BilbLQGc973f",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1233.3157348632812,
|
||||
"y": 168.29967880249023,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 229.03393554687523,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1923498546,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 659,
|
||||
"versionNonce": 2122259328,
|
||||
"isDeleted": false,
|
||||
"id": "eedUyCpr8i1aY_3PHsHAB",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1241.1352844238281,
|
||||
"y": 191.2939567565918,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 216,
|
||||
"height": 35,
|
||||
"seed": 595309038,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Misconfiguration",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1397,
|
||||
"versionNonce": 20077696,
|
||||
"isDeleted": false,
|
||||
"id": "SPkrBrH6DGvkgQXtZQjIJ",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1023.8157043457031,
|
||||
"y": 168.7816276550293,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 200.7496337890626,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1896460914,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 840,
|
||||
"versionNonce": 655338368,
|
||||
"isDeleted": false,
|
||||
"id": "n06MNIqirDmVZBkDg_UPV",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1040.526611328125,
|
||||
"y": 194.3111228942871,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 160,
|
||||
"height": 35,
|
||||
"seed": 1131832750,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1441,
|
||||
"versionNonce": 1393118080,
|
||||
"isDeleted": false,
|
||||
"id": "8SHSNGf7PNddFLi2ZA3Vi",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 673.6463928222656,
|
||||
"y": 167.8159294128418,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 278.48516845703136,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1986948530,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 851,
|
||||
"versionNonce": 2114620544,
|
||||
"isDeleted": false,
|
||||
"id": "3Z5w3RXdgpvP43dlHqq26",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 701.5146789550781,
|
||||
"y": 189.60757064819336,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 216,
|
||||
"height": 35,
|
||||
"seed": 1077804654,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Misconfiguration",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": null,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
}
|
||||
}
|
||||
508
docs/imgs/excalidraw/overview.excalidraw
Normal file
@@ -0,0 +1,508 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
"elements": [
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 476,
|
||||
"versionNonce": 916788210,
|
||||
"isDeleted": false,
|
||||
"id": "BkXuq_6BxgqZGZWc8oCtu",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 599.211669921875,
|
||||
"y": 376.32061767578125,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fd7e14",
|
||||
"width": 1076.4584350585938,
|
||||
"height": 151.39703369140625,
|
||||
"seed": 1632394695,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 423,
|
||||
"versionNonce": 931200686,
|
||||
"isDeleted": false,
|
||||
"id": "YQURTHNPSe05RPSlYRcok",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1119.1937866210938,
|
||||
"y": 403.56756591796875,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 88,
|
||||
"height": 45,
|
||||
"seed": 891391049,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 36,
|
||||
"fontFamily": 1,
|
||||
"text": "Trivy",
|
||||
"baseline": 32,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 758,
|
||||
"versionNonce": 813811122,
|
||||
"isDeleted": false,
|
||||
"id": "6dpF2EyZBtYgO6MrvGj0-",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 922.1328735351562,
|
||||
"y": 470.18975830078125,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 507,
|
||||
"height": 35,
|
||||
"seed": 687997545,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability/Misconfiguration Scanner",
|
||||
"baseline": 25,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 595,
|
||||
"versionNonce": 1705780846,
|
||||
"isDeleted": false,
|
||||
"id": "cpnTMy7L2AUg9IDJppF4H",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 597.4796142578125,
|
||||
"y": 258.9286651611328,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fab005",
|
||||
"width": 349.1224975585937,
|
||||
"height": 103.28388977050778,
|
||||
"seed": 77164935,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 921,
|
||||
"versionNonce": 929185650,
|
||||
"isDeleted": false,
|
||||
"id": "9-blmNVtLesthMSY_f60t",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 655.6057739257812,
|
||||
"y": 292.4844055175781,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 238,
|
||||
"height": 35,
|
||||
"seed": 860091815,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Container Images",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 853,
|
||||
"versionNonce": 377039022,
|
||||
"isDeleted": false,
|
||||
"id": "gugZxhi7ThlcjWY_MFO7q",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 955.929443359375,
|
||||
"y": 262.11351776123047,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#be4bdb",
|
||||
"width": 359.85211181640625,
|
||||
"height": 99.05134582519533,
|
||||
"seed": 1232790121,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 1065,
|
||||
"versionNonce": 126714162,
|
||||
"isDeleted": false,
|
||||
"id": "K48gtpesBxIGJxLTnI2CB",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1064.449462890625,
|
||||
"y": 296.9230194091797,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 137,
|
||||
"height": 35,
|
||||
"seed": 449264361,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Filesystem",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 896,
|
||||
"versionNonce": 585884398,
|
||||
"isDeleted": false,
|
||||
"id": "La6f87LDZ0uEIZB947bXo",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1329.0839233398438,
|
||||
"y": 264.9097213745117,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#12b886",
|
||||
"width": 346.5517578125,
|
||||
"height": 96.3990020751953,
|
||||
"seed": 2005637801,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 1186,
|
||||
"versionNonce": 1013615346,
|
||||
"isDeleted": false,
|
||||
"id": "aOgRPVQ81jhOfkvzjWTMF",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1392.300048828125,
|
||||
"y": 294.1288604736328,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 223,
|
||||
"height": 35,
|
||||
"seed": 1284472935,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Git Repositories",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 974,
|
||||
"versionNonce": 1011959534,
|
||||
"isDeleted": false,
|
||||
"id": "BYJwfkhd1BilbLQGc973f",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1141.5093994140625,
|
||||
"y": 171.09759140014648,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 169.93957519531259,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1923498546,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 403,
|
||||
"versionNonce": 1635608306,
|
||||
"isDeleted": false,
|
||||
"id": "eedUyCpr8i1aY_3PHsHAB",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1149.8379821777344,
|
||||
"y": 197.31159591674805,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 155,
|
||||
"height": 25,
|
||||
"seed": 595309038,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"text": "Misconfiguration",
|
||||
"baseline": 18,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1035,
|
||||
"versionNonce": 1646453614,
|
||||
"isDeleted": false,
|
||||
"id": "SPkrBrH6DGvkgQXtZQjIJ",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 959.9851989746094,
|
||||
"y": 170.4835319519043,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 169.93957519531259,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1896460914,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 532,
|
||||
"versionNonce": 1887556210,
|
||||
"isDeleted": false,
|
||||
"id": "n06MNIqirDmVZBkDg_UPV",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 988.8137817382812,
|
||||
"y": 196.69753646850586,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 114,
|
||||
"height": 25,
|
||||
"seed": 1131832750,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability",
|
||||
"baseline": 18,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1072,
|
||||
"versionNonce": 789595566,
|
||||
"isDeleted": false,
|
||||
"id": "0JP6OL7EFfoH4E4vFARFl",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1508.9087371826172,
|
||||
"y": 170.7038917541504,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 169.93957519531259,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 101784622,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 496,
|
||||
"versionNonce": 1027781682,
|
||||
"isDeleted": false,
|
||||
"id": "jRmlh5MZuRKm3FtbC6qdZ",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1517.237319946289,
|
||||
"y": 196.91789627075195,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 155,
|
||||
"height": 25,
|
||||
"seed": 1950385586,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"text": "Misconfiguration",
|
||||
"baseline": 18,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1133,
|
||||
"versionNonce": 882335726,
|
||||
"isDeleted": false,
|
||||
"id": "EQRF92xU4o9CfeHHvbd-a",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1327.384536743164,
|
||||
"y": 170.0898323059082,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 169.93957519531259,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1379493486,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 569,
|
||||
"versionNonce": 184638962,
|
||||
"isDeleted": false,
|
||||
"id": "_04YR8geM-ar9vZhNZtSj",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1356.213119506836,
|
||||
"y": 196.30383682250977,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 114,
|
||||
"height": 25,
|
||||
"seed": 357105522,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability",
|
||||
"baseline": 18,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1215,
|
||||
"versionNonce": 650195502,
|
||||
"isDeleted": false,
|
||||
"id": "8SHSNGf7PNddFLi2ZA3Vi",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 599.9767150878906,
|
||||
"y": 169.0025749206543,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 344.1738281250001,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1986948530,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 680,
|
||||
"versionNonce": 113561522,
|
||||
"isDeleted": false,
|
||||
"id": "3Z5w3RXdgpvP43dlHqq26",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 700.3721618652344,
|
||||
"y": 190.79421615600586,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 160,
|
||||
"height": 35,
|
||||
"seed": 1077804654,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": null,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
}
|
||||
}
|
||||
631
docs/imgs/excalidraw/repo.excalidraw
Normal file
@@ -0,0 +1,631 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
BIN
docs/imgs/fs.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
docs/imgs/image.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
42
docs/imgs/logo-white.svg
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 25.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="_x30_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="273.277px" height="312.341px" viewBox="0 0 273.277 312.341" enable-background="new 0 0 273.277 312.341"
|
||||
xml:space="preserve">
|
||||
<g display="none">
|
||||
<g display="inline">
|
||||
<path id="XMLID_238_" fill="#F6921E" d="M754.885-766.991c-21.65-2.012-36.066-7.554-55.471-17.526
|
||||
c-34.765-17.865-71.511-25.264-109.482-29.708c-7.552-0.884-15.107-1.971-22.551-3.503c-30.631-6.306-41.022-20.345-31.022-50.036
|
||||
c8.852-26.284,8.129-51.529,4.062-77.9c-3.886-25.202,5.516-42.009,30.232-49.091c26.958-7.724,46.055-23.279,62.176-45.683
|
||||
c22.552-31.342,50.43-32.387,75.678-2.592c13.29,15.683,24.5,33.868,33.206,52.53c15.16,32.498,33.741,62.384,56.465,90.012
|
||||
c8.997,10.939,16.637,23.055,24.312,35.009c14.177,22.079,18.196,45.43,4.449,69.026
|
||||
C812.894-772.342,790.61-767.179,754.885-766.991z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M134.241,178.01c-14.966-6.734-23.812-21.134-23.341-36.425l-31.99-18.474
|
||||
c-2.386,17.699,1.426,36.211,11.026,52.252c10.219,17.074,24.977,29.791,44.305,37.154V178.01L134.241,178.01z"/>
|
||||
<path fill="#FFFFFF" d="M134.241,256.256v-39.66c-20.701-7.561-36.56-21.171-47.443-39.355
|
||||
c-10.295-17.201-14.212-37.138-11.295-56.097l-29.733-17.17C28.736,166.142,66.954,232.356,134.241,256.256z"/>
|
||||
<path fill="#FFFFFF" d="M138.623,216.235v40.021c66.042-24.455,105.685-90.553,88.941-152.077l-29.572,17.228
|
||||
c3.69,20.45,0.473,40.386-9.42,57.065C178.408,195.609,160.66,208.469,138.623,216.235z"/>
|
||||
<path fill="#FFFFFF" d="M162.732,141.756c0.133,14.847-8.593,27.909-24.109,36.253v34.508c20.619-7.517,37.273-19.844,46.802-35.91
|
||||
c9.226-15.555,12.364-34.116,9.199-53.238L162.732,141.756z"/>
|
||||
<path fill="#FFFFFF" d="M167.338,88.702c12.474,6.083,22.634,15.828,29.381,28.179c0.089,0.163,0.172,0.332,0.26,0.496
|
||||
l29.007-16.751c-0.461-0.581-0.905-1.169-1.269-1.758c-10.641-17.213-24.699-30.163-41.784-38.496
|
||||
c-48.231-23.521-107.332-5.786-135.568,40.317l28.937,16.703C95.95,85.802,135.501,73.176,167.338,88.702z"/>
|
||||
<path fill="#FFFFFF" d="M114.557,143.696c0.395,12.594,7.426,24.256,19.684,30.297v-18.6L114.557,143.696z"/>
|
||||
<path fill="#FFFFFF" d="M158.428,139.64c-0.105-0.216-0.208-0.433-0.321-0.645c-2.395-4.49-6.021-8.015-10.487-10.193
|
||||
c-11.485-5.598-25.573-0.979-32.947,10.739l21.968,12.68L158.428,139.64z"/>
|
||||
<path fill="#FFFFFF" d="M149.224,125.515c5.164,2.519,9.351,6.585,12.11,11.758c0.094,0.175,0.175,0.358,0.263,0.537l32.213-18.602
|
||||
c-0.101-0.19-0.198-0.384-0.301-0.572c-6.381-11.683-15.985-20.898-27.774-26.646c-30.119-14.69-67.578-2.707-86.265,27.232
|
||||
l32.037,18.492C119.857,124.323,136.011,119.072,149.224,125.515z"/>
|
||||
<path fill="#FFFFFF" d="M264.965,82.39l-34.137,19.888c18.006,64.017-23.286,133.016-92.204,157.866v43.341l126.341-73.633V82.39z"
|
||||
/>
|
||||
<path fill="#FFFFFF" d="M8.319,82.347v147.466l125.922,73.672v-43.341c-70.174-24.263-110.029-93.387-91.739-158.058L9.921,83.271
|
||||
L8.319,82.347z"/>
|
||||
<path fill="#FFFFFF" d="M138.623,155.413v18.581c12.219-7.071,19.799-18.339,20.386-30.068L138.623,155.413z"/>
|
||||
<path fill="#FFFFFF" d="M10.129,79.195l3.72,2.148L44.196,98.86c29.195-47.754,90.394-66.13,140.341-41.775
|
||||
c17.716,8.64,32.282,22.051,43.292,39.859c0.349,0.563,0.835,1.182,1.362,1.832l33.939-19.599L136.643,6.134L10.129,79.195z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
BIN
docs/imgs/logo.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
docs/imgs/misconf-demo.gif
Normal file
|
After Width: | Height: | Size: 3.4 MiB |
BIN
docs/imgs/misconf.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/imgs/overview.png
Normal file
|
After Width: | Height: | Size: 878 KiB |
BIN
docs/imgs/repo.png
Normal file
|
After Width: | Height: | Size: 226 KiB |
BIN
docs/imgs/vuln-demo.gif
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/imgs/vulnerability.png
Normal file
|
After Width: | Height: | Size: 846 KiB |
49
docs/index.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
hide:
|
||||
- navigation
|
||||
- toc
|
||||
---
|
||||
|
||||
{ align=left }
|
||||
|
||||
`Trivy` (`tri` pronounced like **tri**gger, `vy` pronounced like en**vy**) is a simple and comprehensive [vulnerability][vulnerability]/[misconfiguration][misconf] scanner for containers and other artifacts.
|
||||
A software vulnerability is a glitch, flaw, or weakness present in the software or in an Operating System.
|
||||
`Trivy` detects vulnerabilities of [OS packages][os] (Alpine, RHEL, CentOS, etc.) and [language-specific packages][lang] (Bundler, Composer, npm, yarn, etc.).
|
||||
In addition, `Trivy` scans [Infrastructure as Code (IaC) files][iac] such as Terraform and Kubernetes, to detect potential configuration issues that expose your deployments to the risk of attack.
|
||||
`Trivy` is easy to use. Just install the binary and you're ready to scan.
|
||||
All you need to do for scanning is to specify a target such as an image name of the container.
|
||||
|
||||
<div style="text-align: center">
|
||||
<img src="imgs/overview.png" width="800">
|
||||
</div>
|
||||
|
||||
|
||||
<div style="text-align: center; margin-top: 150px">
|
||||
<h1 id="demo">Demo</h1>
|
||||
</div>
|
||||
|
||||
<figure style="text-aligh: center">
|
||||
<img src="imgs/vuln-demo.gif" width="1000">
|
||||
<figcaption>Demo: Vulnerability Detection</figcaption>
|
||||
</figure>
|
||||
|
||||
<figure style="text-aligh: center">
|
||||
<img src="imgs/misconf-demo.gif" width="1000">
|
||||
<figcaption>Demo: Misconfiguration Detection</figcaption>
|
||||
</figure>
|
||||
|
||||
---
|
||||
|
||||
Trivy is an [Aqua Security][aquasec] open source project.
|
||||
Learn about our open source work and portfolio [here][oss].
|
||||
Contact us about any matter by opening a GitHub Discussion [here][discussions]
|
||||
|
||||
[vulnerability]: vulnerability/scanning/index.md
|
||||
[misconf]: misconfiguration/index.md
|
||||
[os]: vulnerability/detection/os.md
|
||||
[lang]: vulnerability/detection/language.md
|
||||
[iac]: misconfiguration/iac.md
|
||||
|
||||
[aquasec]: https://aquasec.com
|
||||
[oss]: https://www.aquasec.com/products/open-source-projects/
|
||||
[discussions]: https://github.com/aquasecurity/trivy/discussions
|
||||
43
docs/misconfiguration/comparison/conftest.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# vs Conftest
|
||||
[Conftest][conftest] is a really nice tool to help you write tests against structured configuration data.
|
||||
Misconfiguration detection in Trivy is heavily inspired by Conftest and provides similar features Conftest has.
|
||||
This section describes the differences between Trivy and Conftest.
|
||||
|
||||
| Feature | Trivy | Conftest |
|
||||
| --------------------------- | -------------------- | -------------------- |
|
||||
| Support Rego Language | :material-check: | :material-check: |
|
||||
| Built-in Policies | :material-check: | :material-close: |
|
||||
| Custom Policies | :material-check: | :material-check: |
|
||||
| Custom Data | :material-check: | :material-check: |
|
||||
| Combine | :material-check: | :material-check: |
|
||||
| Combine per Policy | :material-check: | :material-close: |
|
||||
| Policy Input Selector[^1] | :material-check: | :material-close: |
|
||||
| Policy Metadata[^2] | :material-check: | :material-close:[^3] |
|
||||
| Filtering by Severity | :material-check: | :material-close: |
|
||||
| Rule-based Exceptions | :material-check: | :material-check: |
|
||||
| Namespace-based Exceptions | :material-check: | :material-close: |
|
||||
| Sharing Policies | :material-close: | :material-check: |
|
||||
| Show Successes | :material-check: | :material-close: |
|
||||
| Flexible Exit Code | :material-check: | :material-close: |
|
||||
| Rego Unit Tests | :material-close:[^4] | :material-check: |
|
||||
| Go Testing | :material-check: | :material-close: |
|
||||
| Verbose Trace | :material-check: | :material-check: |
|
||||
| Supported Formats | 6 formats[^5] | 14 formats[^6] |
|
||||
|
||||
Trivy offers built-in policies and a variety of options, while Conftest only supports custom policies.
|
||||
In other words, Conftest is simpler and lighter.
|
||||
|
||||
Conftest is a general testing tool for configuration files, and Trivy is more security-focused.
|
||||
People who need an out-of-the-box misconfiguration scanner should use Trivy.
|
||||
People who don't need built-in policies and write your policies should use Conftest.
|
||||
|
||||
[^1]: Pass only the types of configuration file as input, specified in selector
|
||||
[^2]: To enrich the results such as ID, Title, Description, etc.
|
||||
[^3]: Conftest supports [structured errors in rules][conftest-structured], but they are free format and not natively supported by Conftest.
|
||||
[^4]: Trivy is not able to run `*_test.rego` like `conftest verify`.
|
||||
[^5]: Dockerfile, HCL, HCL2, JSON, TOML, and YAML
|
||||
[^6]: CUE, Dockerfile, EDN, HCL, HCL2, HOCON, Ignore files, INI, JSON, Jsonnet, TOML, VCL, XML, and YAML
|
||||
|
||||
|
||||
[conftest-structured]: https://github.com/open-policy-agent/conftest/pull/243
|
||||
[conftest]: https://github.com/open-policy-agent/conftest
|
||||
26
docs/misconfiguration/comparison/tfsec.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# vs tfsec
|
||||
[tfsec][tfsec] uses static analysis of your Terraform templates to spot potential security issues.
|
||||
Trivy uses tfsec internally to scan Terraform HCL files, but Trivy doesn't support some features provided by tfsec.
|
||||
This section describes the differences between Trivy and tfsec.
|
||||
|
||||
| Feature | Trivy | tfsec |
|
||||
| --------------------------- | --------------------------------------- | -------------------- |
|
||||
| Built-in Policies | :material-check: | :material-check: |
|
||||
| Custom Policies | Rego[^1] | JSON and YAML |
|
||||
| Policy Metadata[^2] | :material-check: | :material-check: |
|
||||
| Show Successes | :material-check: | :material-check: |
|
||||
| Disable Policies | :material-check: | :material-check: |
|
||||
| Show Issue Lines | :material-close: | :material-check: |
|
||||
| Support .tfvars | :material-close: | :material-check: |
|
||||
| View Statistics | :material-close: | :material-check: |
|
||||
| Filtering by Severity | :material-check: | :material-close: |
|
||||
| Supported Formats | Dockerfile, JSON, YAML, Terraform, etc. | Terraform |
|
||||
|
||||
[^1]: Terraform HCL files are not supported.
|
||||
[^2]: To enrich the results such as ID, Title, Description, Severity, etc.
|
||||
|
||||
tfsec is designed for Terraform.
|
||||
People who use only Terraform should use tfsec.
|
||||
People who want to scan a wide range of configuration files should use Trivy.
|
||||
|
||||
[tfsec]: https://github.com/tfsec/tfsec
|
||||
44
docs/misconfiguration/custom/combine.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# 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",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
35
docs/misconfiguration/custom/data.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
$ 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:
|
||||
|
||||
```rego
|
||||
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.
|
||||
|
||||
```bash
|
||||
$ trivy conf --policy ./policy --data data --namespaces user ./configs
|
||||
```
|
||||
225
docs/misconfiguration/custom/debug.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# 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.
|
||||
|
||||
```bash
|
||||
$ trivy conf --trace configs/
|
||||
2021-07-11T16:45:58.493+0300 INFO Detected config files: 1
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
|
||||
ID: DS002
|
||||
File: Dockerfile
|
||||
Namespace: appshield.dockerfile.DS002
|
||||
Query: data.appshield.dockerfile.DS002.deny
|
||||
Message: Last USER command in Dockerfile should not be 'root'
|
||||
TRACE Enter data.appshield.dockerfile.DS002.deny = _
|
||||
TRACE | Eval data.appshield.dockerfile.DS002.deny = _
|
||||
TRACE | Index data.appshield.dockerfile.DS002.deny matched 2 rules)
|
||||
TRACE | Enter data.appshield.dockerfile.DS002.deny
|
||||
TRACE | | Eval data.appshield.dockerfile.DS002.fail_user_count
|
||||
TRACE | | Index data.appshield.dockerfile.DS002.fail_user_count (matched 1 rule)
|
||||
TRACE | | Enter data.appshield.dockerfile.DS002.fail_user_count
|
||||
TRACE | | | Eval __local559__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Index data.appshield.dockerfile.DS002.get_user (matched 1 rule)
|
||||
TRACE | | | Enter data.appshield.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 | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = 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 | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = 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 count(__local559__, __local391__)
|
||||
TRACE | | | Eval lt(__local391__, 1)
|
||||
TRACE | | | Fail lt(__local391__, 1)
|
||||
TRACE | | | Redo count(__local559__, __local391__)
|
||||
TRACE | | | Redo __local559__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | Fail data.appshield.dockerfile.DS002.fail_user_count
|
||||
TRACE | Enter data.appshield.dockerfile.DS002.deny
|
||||
TRACE | | Eval data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | Index data.appshield.dockerfile.DS002.fail_last_user_root (matched 1 rule)
|
||||
TRACE | | Enter data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | | Eval __local560__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Index data.appshield.dockerfile.DS002.get_user (matched 1 rule)
|
||||
TRACE | | | Enter data.appshield.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 | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = 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 | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = 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 cast_array(__local560__, __local392__)
|
||||
TRACE | | | Eval user = __local392__
|
||||
TRACE | | | Eval __local561__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Index data.appshield.dockerfile.DS002.get_user (matched 1 rule)
|
||||
TRACE | | | Enter data.appshield.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 | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail 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 instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = 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 | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = 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 count(__local561__, __local393__)
|
||||
TRACE | | | Eval len = __local393__
|
||||
TRACE | | | Eval minus(len, 1, __local394__)
|
||||
TRACE | | | Eval user[__local394__] = "root"
|
||||
TRACE | | | Exit data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | Eval res = "Last USER command in Dockerfile should not be 'root'"
|
||||
TRACE | | Exit data.appshield.dockerfile.DS002.deny
|
||||
TRACE | Redo data.appshield.dockerfile.DS002.deny
|
||||
TRACE | | Redo res = "Last USER command in Dockerfile should not be 'root'"
|
||||
TRACE | | Redo data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | Redo data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | | Redo user[__local394__] = "root"
|
||||
TRACE | | | Redo minus(len, 1, __local394__)
|
||||
TRACE | | | Redo len = __local393__
|
||||
TRACE | | | Redo count(__local561__, __local393__)
|
||||
TRACE | | | Redo __local561__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo user = __local392__
|
||||
TRACE | | | Redo cast_array(__local560__, __local392__)
|
||||
TRACE | | | Redo __local560__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | Exit data.appshield.dockerfile.DS002.deny = _
|
||||
TRACE Redo data.appshield.dockerfile.DS002.deny = _
|
||||
TRACE | Redo data.appshield.dockerfile.DS002.deny = _
|
||||
```
|
||||
296
docs/misconfiguration/custom/examples.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# Examples
|
||||
|
||||
## Custom Policy
|
||||
### Kubernetes
|
||||
See [here][k8s].
|
||||
|
||||
The custom policy is defined in `user.kubernetes.ID001` package.
|
||||
You need to pass the package prefix you want to evaluate through `--namespaces` option.
|
||||
In this case, the package prefix should be `user`, `user.kuberntes`, or `user.kubernetes.ID001`.
|
||||
|
||||
### Dockerfile
|
||||
See [here][dockerfile].
|
||||
|
||||
The input will be a dictionary of stages.
|
||||
|
||||
#### Single Stage
|
||||
|
||||
??? example
|
||||
Dockerfile
|
||||
```dockerfile
|
||||
FROM foo
|
||||
COPY . /
|
||||
RUN echo hello
|
||||
```
|
||||
|
||||
Rego Input
|
||||
```json
|
||||
{
|
||||
"stages": {
|
||||
"foo": [
|
||||
{
|
||||
"Cmd": "from",
|
||||
"EndLine": 1,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "FROM foo",
|
||||
"Stage": 0,
|
||||
"StartLine": 1,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"foo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "copy",
|
||||
"EndLine": 2,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "COPY . /",
|
||||
"Stage": 0,
|
||||
"StartLine": 2,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
".",
|
||||
"/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "run",
|
||||
"EndLine": 3,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "RUN echo hello",
|
||||
"Stage": 0,
|
||||
"StartLine": 3,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"echo hello"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Multi Stage
|
||||
|
||||
??? example
|
||||
Dockerfile
|
||||
```dockerfile
|
||||
FROM golang:1.16 AS builder
|
||||
WORKDIR /go/src/github.com/alexellis/href-counter/
|
||||
RUN go get -d -v golang.org/x/net/html
|
||||
COPY app.go .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk --no-cache add ca-certificates \
|
||||
&& apk add --no-cache bash
|
||||
WORKDIR /root/
|
||||
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
|
||||
CMD ["./app"]
|
||||
```
|
||||
|
||||
Rego Input
|
||||
```json
|
||||
{
|
||||
"stages": {
|
||||
"alpine:latest": [
|
||||
{
|
||||
"Cmd": "from",
|
||||
"EndLine": 7,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "FROM alpine:latest",
|
||||
"Stage": 1,
|
||||
"StartLine": 7,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"alpine:latest"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "run",
|
||||
"EndLine": 9,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "RUN apk --no-cache add ca-certificates \u0026\u0026 apk add --no-cache bash",
|
||||
"Stage": 1,
|
||||
"StartLine": 8,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"apk --no-cache add ca-certificates \u0026\u0026 apk add --no-cache bash"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "workdir",
|
||||
"EndLine": 10,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "WORKDIR /root/",
|
||||
"Stage": 1,
|
||||
"StartLine": 10,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"/root/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "copy",
|
||||
"EndLine": 11,
|
||||
"Flags": [
|
||||
"--from=builder"
|
||||
],
|
||||
"JSON": false,
|
||||
"Original": "COPY --from=builder /go/src/github.com/alexellis/href-counter/app .",
|
||||
"Stage": 1,
|
||||
"StartLine": 11,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"/go/src/github.com/alexellis/href-counter/app",
|
||||
"."
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "cmd",
|
||||
"EndLine": 12,
|
||||
"Flags": [],
|
||||
"JSON": true,
|
||||
"Original": "CMD [\"./app\"]",
|
||||
"Stage": 1,
|
||||
"StartLine": 12,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"./app"
|
||||
]
|
||||
}
|
||||
],
|
||||
"golang:1.16 AS builder": [
|
||||
{
|
||||
"Cmd": "from",
|
||||
"EndLine": 1,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "FROM golang:1.16 AS builder",
|
||||
"Stage": 0,
|
||||
"StartLine": 1,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"golang:1.16",
|
||||
"AS",
|
||||
"builder"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "workdir",
|
||||
"EndLine": 2,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "WORKDIR /go/src/github.com/alexellis/href-counter/",
|
||||
"Stage": 0,
|
||||
"StartLine": 2,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"/go/src/github.com/alexellis/href-counter/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "run",
|
||||
"EndLine": 3,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "RUN go get -d -v golang.org/x/net/html",
|
||||
"Stage": 0,
|
||||
"StartLine": 3,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"go get -d -v golang.org/x/net/html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "copy",
|
||||
"EndLine": 4,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "COPY app.go .",
|
||||
"Stage": 0,
|
||||
"StartLine": 4,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"app.go",
|
||||
"."
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "run",
|
||||
"EndLine": 5,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .",
|
||||
"Stage": 0,
|
||||
"StartLine": 5,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app ."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
See [here][compose].
|
||||
|
||||
Docker Compose uses YAML format for configurations. You can apply your Rego policies to `docker-compose.yml`.
|
||||
|
||||
### HCL
|
||||
See [here][hcl].
|
||||
|
||||
Trivy parses HCL files and converts into structured data.
|
||||
|
||||
!!! warning
|
||||
Terraform HCL files are not supported yet.
|
||||
|
||||
### Terraform Plan
|
||||
See [here][tfplan].
|
||||
|
||||
Use the command [terraform show][terraform-show] to convert the Terraform plan into JSON so that OPA can read the plan.
|
||||
|
||||
```bash
|
||||
$ terraform init
|
||||
$ terraform plan --out tfplan.binary
|
||||
$ terraform show -json tfplan.binary > tfplan.json
|
||||
```
|
||||
|
||||
For more details, see also [OPA document][opa-terraform].
|
||||
|
||||
### Serverless Framework
|
||||
See [here][serverless].
|
||||
|
||||
Server Framework uses YAML format for configurations. You can apply your Rego policies to `serverless.yaml`.
|
||||
|
||||
## Custom Data
|
||||
See [here][data].
|
||||
|
||||
## Combined Input
|
||||
See [here][combine].
|
||||
|
||||
## Go Testing
|
||||
See [here][go-testing].
|
||||
|
||||
[k8s]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/kubernetes/
|
||||
[dockerfile]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/dockerfile/
|
||||
[compose]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/docker-compose/
|
||||
[hcl]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/hcl/
|
||||
[serverless]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/serverless/
|
||||
[tfplan]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/terraform-plan/
|
||||
[terraform-show]: https://www.terraform.io/docs/cli/commands/show.html
|
||||
[opa-terraform]: https://www.openpolicyagent.org/docs/latest/terraform/
|
||||
|
||||
[custom]: https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy
|
||||
[data]: https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-data
|
||||
[combine]: https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/combine
|
||||
[go-testing]: https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/go-testing
|
||||
|
||||
183
docs/misconfiguration/custom/index.md
Normal file
@@ -0,0 +1,183 @@
|
||||
# Custom Policies
|
||||
|
||||
## Overview
|
||||
You can write custom policies in [Rego][rego].
|
||||
Once you finish writing custom policies, you can pass the directory where those policies are stored with `--policy` option.
|
||||
|
||||
``` bash
|
||||
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` |
|
||||
| TOML | `*.toml` |
|
||||
| HCL | `*.hcl`, `*.hcl1`, and `*.hcl2` |
|
||||
| Dockerfile | `Dockerfile`, `Dockerfile.*`, and `*.Dockerfile` |
|
||||
|
||||
### Configuration languages
|
||||
In the above general file formats, Trivy automatically identifies the following types of configuration files:
|
||||
|
||||
- Ansible (YAML)
|
||||
- CloudFormation (JSON/YAML)
|
||||
- Kubernetes (JSON/YAML)
|
||||
|
||||
This is useful for filtering inputs, as described below.
|
||||
|
||||
!!! warning
|
||||
Custom policies do not support Terraform at the moment.
|
||||
|
||||
## Rego format
|
||||
A single package must contain only one policy.
|
||||
|
||||
!!!example
|
||||
``` rego
|
||||
package user.kubernetes.ID001
|
||||
|
||||
__rego_metadata__ := {
|
||||
"id": "ID001",
|
||||
"title": "Deployment not allowed",
|
||||
"severity": "LOW",
|
||||
"type": "Custom Kubernetes Check",
|
||||
"description": "Deployments are not allowed because of some reasons.",
|
||||
}
|
||||
|
||||
__rego_input__ := {
|
||||
"selector": [
|
||||
{"type": "kubernetes"},
|
||||
],
|
||||
}
|
||||
|
||||
deny[msg] {
|
||||
input.kind == "Deployment"
|
||||
msg = sprintf("Found deployment '%s' but deployments are not allowed", [input.metadata.name])
|
||||
}
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
`package` (required)
|
||||
: - MUST follow the Rego's [specification][package]
|
||||
- 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
|
||||
|
||||
`__rego_metadata__` (optional)
|
||||
: - SHOULD be defined for clarity since these values will be displayed in the scan results
|
||||
|
||||
`__rego_input__` (optional)
|
||||
: - MAY be defined when you want to specify input format
|
||||
|
||||
`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 `string`
|
||||
- Although `object` with `msg` field is accepted, other fields are dropped and `string` is recommended.
|
||||
- e.g. `{"msg": "deny message", "details": "something"}`
|
||||
|
||||
|
||||
### Package
|
||||
A package name must be unique per policy.
|
||||
|
||||
!!!example
|
||||
``` rego
|
||||
package user.kubernetes.ID001
|
||||
```
|
||||
|
||||
By default, only `appshield.*` packages will be evaluated.
|
||||
If you define custom packages, you have to specify the package prefix via `--namespaces` option.
|
||||
|
||||
``` bash
|
||||
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.
|
||||
|
||||
!!!example
|
||||
``` rego
|
||||
__rego_metadata__ := {
|
||||
"id": "ID001",
|
||||
"title": "Deployment not allowed",
|
||||
"severity": "LOW",
|
||||
"type": "Custom Kubernetes Check",
|
||||
"description": "Deployments are not allowed because of some reasons.",
|
||||
"recommended_actions": "Remove Deployment",
|
||||
"url": "https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits",
|
||||
}
|
||||
```
|
||||
|
||||
All fields under `__rego_metadata__` are optional.
|
||||
|
||||
| Field name | Allowed values | Default value | In table | In JSON |
|
||||
| ------------------ | ------------------------------------| :-----------: | :----------------: |:---------------: |
|
||||
| id | Any characters | N/A | :material-check: | :material-check: |
|
||||
| title | Any characters | N/A | :material-check: | :material-check: |
|
||||
| severity | `LOW`, `MEDIUM`, `HIGH`, `CRITICAL` | UNKNOWN | :material-check: | :material-check: |
|
||||
| type | Any characters | N/A | :material-check: | :material-check: |
|
||||
| description | Any characters | | :material-close: | :material-check: |
|
||||
| recommended_actions| Any characters | | :material-close: | :material-check: |
|
||||
| url | Any characters | | :material-close: | :material-check: |
|
||||
|
||||
Some fields are displayed in scan results.
|
||||
|
||||
``` bash
|
||||
deployment.yaml (kubernetes)
|
||||
============================
|
||||
Tests: 28 (SUCCESSES: 14, FAILURES: 14, EXCEPTIONS: 0)
|
||||
Failures: 14 (HIGH: 1)
|
||||
|
||||
+---------------------------+------------+-------------------------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+-------------------------------------+----------+------------------------------------------+
|
||||
| Custom Kubernetes Check | ID001 | Deployment not allowed | LOW | Found deployment 'test' but deployments |
|
||||
| | | | | are not allowed |
|
||||
+---------------------------+------------+-------------------------------------+----------+------------------------------------------+
|
||||
```
|
||||
|
||||
### Input
|
||||
You can specify input format via `__rego_input__`.
|
||||
All fields under `__rego_input` are optional.
|
||||
|
||||
!!!example
|
||||
``` rego
|
||||
__rego_input__ := {
|
||||
"combine": false,
|
||||
"selector": [
|
||||
{"type": "kubernetes"},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
`combine` (boolean)
|
||||
: The details is [here](combine.md).
|
||||
|
||||
`selector` (array)
|
||||
: This option filters the input by file formats or configuration languages.
|
||||
In the above example, Trivy passes only Kubernetes files to this policy.
|
||||
Even if Dockerfile exists in the specified directory, it will not be passed to the policy as input.
|
||||
|
||||
When configuration language such as Kubernetes is not identified, file format such as JSON will be used as `type`.
|
||||
When 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`, `ansible`, `cloudformation`, `json`, `yaml`, `toml`, or `hcl`.
|
||||
|
||||
[rego]: https://www.openpolicyagent.org/docs/latest/policy-language/
|
||||
[package]: https://www.openpolicyagent.org/docs/latest/policy-language/#packages
|
||||