@@ -11,6 +11,23 @@ import (
1111 "github.com/golang-jwt/jwt/v5"
1212)
1313
14+ func newTestVerifier (t * testing.T , publicKey ed25519.PublicKey , prefixes []string ) * oidc.Verifier {
15+ t .Helper ()
16+
17+ verifier , err := oidc .NewVerifier (oidc.Config {
18+ Issuer : "https://token.actions.githubusercontent.com" ,
19+ Audience : "asb-control-plane" ,
20+ AllowedSubjectPrefixes : prefixes ,
21+ Keyfunc : func (context.Context , * jwt.Token ) (any , error ) {
22+ return publicKey , nil
23+ },
24+ })
25+ if err != nil {
26+ t .Fatalf ("NewVerifier() error = %v" , err )
27+ }
28+ return verifier
29+ }
30+
1431func TestVerifier_VerifyGitHubActionsToken (t * testing.T ) {
1532 t .Parallel ()
1633
@@ -41,17 +58,7 @@ func TestVerifier_VerifyGitHubActionsToken(t *testing.T) {
4158 t .Fatalf ("SignedString() error = %v" , err )
4259 }
4360
44- verifier , err := oidc .NewVerifier (oidc.Config {
45- Issuer : "https://token.actions.githubusercontent.com" ,
46- Audience : "asb-control-plane" ,
47- AllowedSubjectPrefixes : []string {"repo:evalops/" },
48- Keyfunc : func (context.Context , * jwt.Token ) (any , error ) {
49- return publicKey , nil
50- },
51- })
52- if err != nil {
53- t .Fatalf ("NewVerifier() error = %v" , err )
54- }
61+ verifier := newTestVerifier (t , publicKey , []string {"repo:evalops/" })
5562
5663 identity , err := verifier .Verify (context .Background (), & core.Attestation {
5764 Kind : core .AttestationKindOIDCJWT ,
@@ -93,22 +100,128 @@ func TestVerifier_RejectsUnexpectedSubjectPrefix(t *testing.T) {
93100 t .Fatalf ("SignedString() error = %v" , err )
94101 }
95102
96- verifier , err := oidc .NewVerifier (oidc.Config {
97- Issuer : "https://token.actions.githubusercontent.com" ,
98- Audience : "asb-control-plane" ,
99- AllowedSubjectPrefixes : []string {"repo:evalops/" },
100- Keyfunc : func (context.Context , * jwt.Token ) (any , error ) {
101- return publicKey , nil
102- },
103+ verifier := newTestVerifier (t , publicKey , []string {"repo:evalops/" })
104+
105+ if _ , err := verifier .Verify (context .Background (), & core.Attestation {
106+ Kind : core .AttestationKindOIDCJWT ,
107+ Token : raw ,
108+ }); err == nil {
109+ t .Fatal ("Verify() error = nil, want non-nil" )
110+ }
111+ }
112+
113+ func TestVerifier_AllowsAnySubjectWhenPrefixesUnset (t * testing.T ) {
114+ t .Parallel ()
115+
116+ publicKey , privateKey , err := ed25519 .GenerateKey (nil )
117+ if err != nil {
118+ t .Fatalf ("GenerateKey() error = %v" , err )
119+ }
120+
121+ token := jwt .NewWithClaims (jwt .SigningMethodEdDSA , jwt.MapClaims {
122+ "iss" : "https://token.actions.githubusercontent.com" ,
123+ "sub" : "repo:other-org/repo:ref:refs/heads/main" ,
124+ "aud" : "asb-control-plane" ,
125+ "exp" : time .Now ().Add (5 * time .Minute ).Unix (),
126+ "iat" : time .Now ().Add (- time .Minute ).Unix (),
103127 })
128+ raw , err := token .SignedString (privateKey )
104129 if err != nil {
105- t .Fatalf ("NewVerifier() error = %v" , err )
130+ t .Fatalf ("SignedString() error = %v" , err )
131+ }
132+
133+ verifier := newTestVerifier (t , publicKey , nil )
134+ if _ , err := verifier .Verify (context .Background (), & core.Attestation {
135+ Kind : core .AttestationKindOIDCJWT ,
136+ Token : raw ,
137+ }); err != nil {
138+ t .Fatalf ("Verify() error = %v" , err )
139+ }
140+ }
141+
142+ func TestVerifier_RejectsExpiredToken (t * testing.T ) {
143+ t .Parallel ()
144+
145+ publicKey , privateKey , err := ed25519 .GenerateKey (nil )
146+ if err != nil {
147+ t .Fatalf ("GenerateKey() error = %v" , err )
148+ }
149+
150+ token := jwt .NewWithClaims (jwt .SigningMethodEdDSA , jwt.MapClaims {
151+ "iss" : "https://token.actions.githubusercontent.com" ,
152+ "sub" : "repo:evalops/asb:ref:refs/heads/main" ,
153+ "aud" : "asb-control-plane" ,
154+ "exp" : time .Now ().Add (- time .Minute ).Unix (),
155+ "iat" : time .Now ().Add (- 2 * time .Minute ).Unix (),
156+ })
157+ raw , err := token .SignedString (privateKey )
158+ if err != nil {
159+ t .Fatalf ("SignedString() error = %v" , err )
106160 }
107161
162+ verifier := newTestVerifier (t , publicKey , []string {"repo:evalops/" })
108163 if _ , err := verifier .Verify (context .Background (), & core.Attestation {
109164 Kind : core .AttestationKindOIDCJWT ,
110165 Token : raw ,
111166 }); err == nil {
112- t .Fatal ("Verify() error = nil, want non-nil" )
167+ t .Fatal ("Verify() error = nil, want expired token failure" )
168+ }
169+ }
170+
171+ func TestVerifier_RejectsTokenBeforeNotBefore (t * testing.T ) {
172+ t .Parallel ()
173+
174+ publicKey , privateKey , err := ed25519 .GenerateKey (nil )
175+ if err != nil {
176+ t .Fatalf ("GenerateKey() error = %v" , err )
177+ }
178+
179+ token := jwt .NewWithClaims (jwt .SigningMethodEdDSA , jwt.MapClaims {
180+ "iss" : "https://token.actions.githubusercontent.com" ,
181+ "sub" : "repo:evalops/asb:ref:refs/heads/main" ,
182+ "aud" : "asb-control-plane" ,
183+ "exp" : time .Now ().Add (5 * time .Minute ).Unix (),
184+ "iat" : time .Now ().Add (- time .Minute ).Unix (),
185+ "nbf" : time .Now ().Add (time .Minute ).Unix (),
186+ })
187+ raw , err := token .SignedString (privateKey )
188+ if err != nil {
189+ t .Fatalf ("SignedString() error = %v" , err )
190+ }
191+
192+ verifier := newTestVerifier (t , publicKey , []string {"repo:evalops/" })
193+ if _ , err := verifier .Verify (context .Background (), & core.Attestation {
194+ Kind : core .AttestationKindOIDCJWT ,
195+ Token : raw ,
196+ }); err == nil {
197+ t .Fatal ("Verify() error = nil, want not-before validation failure" )
198+ }
199+ }
200+
201+ func TestVerifier_RejectsUnexpectedSigningMethod (t * testing.T ) {
202+ t .Parallel ()
203+
204+ publicKey , _ , err := ed25519 .GenerateKey (nil )
205+ if err != nil {
206+ t .Fatalf ("GenerateKey() error = %v" , err )
207+ }
208+
209+ token := jwt .NewWithClaims (jwt .SigningMethodHS256 , jwt.MapClaims {
210+ "iss" : "https://token.actions.githubusercontent.com" ,
211+ "sub" : "repo:evalops/asb:ref:refs/heads/main" ,
212+ "aud" : "asb-control-plane" ,
213+ "exp" : time .Now ().Add (5 * time .Minute ).Unix (),
214+ })
215+ raw , err := token .SignedString ([]byte ("shared-secret" ))
216+ if err != nil {
217+ t .Fatalf ("SignedString() error = %v" , err )
218+ }
219+
220+ verifier := newTestVerifier (t , publicKey , []string {"repo:evalops/" })
221+ if _ , err := verifier .Verify (context .Background (), & core.Attestation {
222+ Kind : core .AttestationKindOIDCJWT ,
223+ Token : raw ,
224+ }); err == nil {
225+ t .Fatal ("Verify() error = nil, want signing-method failure" )
113226 }
114227}
0 commit comments