@@ -10,61 +10,87 @@ const finding = {
1010 VulnerabilityID : "CVE-1" ,
1111} ;
1212const report = { Results : [ { Vulnerabilities : [ finding ] } ] } ;
13- const policy = { baseline : [ ] , exceptions : [ ] , schemaVersion : 1 } ;
13+ const policy = { exceptions : [ ] , schemaVersion : 2 } ;
14+ const digest = `sha256:${ "a" . repeat ( 64 ) } ` ;
15+ const subject = { digest, platform : "linux/amd64" , reference : `registry.example/server@${ digest } ` } ;
16+ const now = new Date ( "2026-09-01T00:00:00Z" ) ;
1417
15- await test ( "rejects a new actionable fixed vulnerability " , ( ) => {
18+ await test ( "rejects a high vulnerability without a disposition " , ( ) => {
1619 assert . deepEqual ( evaluate ( "server" , report , policy ) . rejected , [ "server|CVE-1|lib|1" ] ) ;
1720} ) ;
1821
19- await test ( "accepts an explicitly baselined installed version" , ( ) => {
20- assert . deepEqual (
21- evaluate ( "server" , report , { ...policy , baseline : [ "server|CVE-1|lib|1" ] } ) . rejected ,
22- [ ] ,
23- ) ;
24- } ) ;
25-
26- await test ( "does not classify an unfixed vulnerability as actionable" , ( ) => {
22+ await test ( "requires a disposition even when no fixed version exists" , ( ) => {
2723 assert . deepEqual (
2824 evaluate (
2925 "server" ,
3026 { Results : [ { Vulnerabilities : [ { ...finding , FixedVersion : "" } ] } ] } ,
3127 policy ,
3228 ) . rejected ,
33- [ ] ,
29+ [ "server|CVE-1|lib|1" ] ,
3430 ) ;
3531} ) ;
3632
3733await test ( "accepts an owned, justified, unexpired exception" , ( ) => {
3834 const exceptions = [
3935 {
40- expires : "2099-01-01T00:00:00Z" ,
36+ digest,
37+ evidence : "https://github.com/example/project/issues/1" ,
38+ expires : "2026-10-01T00:00:00Z" ,
4139 image : "server" ,
4240 installedVersion : "1" ,
4341 justification : "not reachable in the deployed configuration" ,
4442 owner : "@security" ,
4543 package : "lib" ,
44+ platform : "linux/amd64" ,
45+ status : "not_affected" ,
4646 vulnerability : "CVE-1" ,
4747 } ,
4848 ] ;
49- assert . deepEqual ( evaluate ( "server" , report , { ...policy , exceptions } ) . rejected , [ ] ) ;
5049 assert . deepEqual (
51- evaluate ( "server" , report , {
52- ...policy ,
53- exceptions : [ { ...exceptions [ 0 ] , installedVersion : "0" } ] ,
54- } ) . rejected ,
50+ evaluate (
51+ "server" ,
52+ { ...report , ArtifactName : subject . reference } ,
53+ { ...policy , exceptions } ,
54+ now ,
55+ subject ,
56+ ) . rejected ,
57+ [ ] ,
58+ ) ;
59+ assert . deepEqual (
60+ evaluate (
61+ "server" ,
62+ { ...report , ArtifactName : subject . reference } ,
63+ { ...policy , exceptions : [ { ...exceptions [ 0 ] , installedVersion : "0" } ] } ,
64+ now ,
65+ subject ,
66+ ) . rejected ,
67+ [ "server|CVE-1|lib|1" ] ,
68+ ) ;
69+ assert . deepEqual (
70+ evaluate (
71+ "server" ,
72+ { ...report , ArtifactName : subject . reference } ,
73+ { ...policy , exceptions : [ { ...exceptions [ 0 ] , digest : `sha256:${ "b" . repeat ( 64 ) } ` } ] } ,
74+ now ,
75+ subject ,
76+ ) . rejected ,
5577 [ "server|CVE-1|lib|1" ] ,
5678 ) ;
5779} ) ;
5880
5981await test ( "rejects expired and malformed exceptions" , ( ) => {
6082 const exceptions = [
6183 {
84+ digest,
85+ evidence : "https://github.com/example/project/issues/1" ,
6286 expires : "2020-01-01T00:00:00Z" ,
6387 image : "server" ,
6488 installedVersion : "1" ,
6589 justification : "reviewed" ,
6690 owner : "@security" ,
6791 package : "lib" ,
92+ platform : "linux/amd64" ,
93+ status : "affected" ,
6894 vulnerability : "CVE-1" ,
6995 } ,
7096 ] ;
@@ -77,4 +103,33 @@ await test("rejects expired and malformed exceptions", () => {
77103 ( ) => evaluate ( "server" , { Results : [ { Vulnerabilities : [ { Severity : "HIGH" } ] } ] } , policy ) ,
78104 / m i s s i n g I n s t a l l e d V e r s i o n / ,
79105 ) ;
106+ assert . match (
107+ evaluate ( "server" , report , {
108+ ...policy ,
109+ exceptions : [ exceptions [ 0 ] , exceptions [ 0 ] ] ,
110+ } ) . errors . join ( "\n" ) ,
111+ / d u p l i c a t e e x c e p t i o n / ,
112+ ) ;
113+ assert . match (
114+ evaluate (
115+ "server" ,
116+ report ,
117+ {
118+ ...policy ,
119+ exceptions : [ { ...exceptions [ 0 ] , expires : "2027-01-01T00:00:00Z" } ] ,
120+ } ,
121+ now ,
122+ ) . errors . join ( "\n" ) ,
123+ / 9 0 - d a y l i m i t / ,
124+ ) ;
125+ assert . match (
126+ evaluate (
127+ "server" ,
128+ { ...report , ArtifactName : "registry.example/server@sha256:wrong" } ,
129+ policy ,
130+ new Date ( ) ,
131+ subject ,
132+ ) . errors . join ( "\n" ) ,
133+ / T r i v y r e p o r t i s f o r / ,
134+ ) ;
80135} ) ;
0 commit comments