@@ -721,7 +721,7 @@ func TestOIDCURLsAreAuthenticated(t *testing.T) {
721721 },
722722 urlMocks : []mockHttpRequest {},
723723 expectedLogLines : []string {
724- "registered aws OIDC credentials for npm registry: npm.example.com" ,
724+ "registered aws OIDC credentials for npm registry: https:// npm.example.com" ,
725725 },
726726 urlsToAuthenticate : []string {
727727 "https://npm.example.com/some-package" ,
@@ -743,7 +743,7 @@ func TestOIDCURLsAreAuthenticated(t *testing.T) {
743743 },
744744 urlMocks : []mockHttpRequest {},
745745 expectedLogLines : []string {
746- "registered azure OIDC credentials for npm registry: npm.example.com" ,
746+ "registered azure OIDC credentials for npm registry: https:// npm.example.com" ,
747747 },
748748 urlsToAuthenticate : []string {
749749 "https://npm.example.com/some-package" ,
@@ -764,7 +764,7 @@ func TestOIDCURLsAreAuthenticated(t *testing.T) {
764764 },
765765 urlMocks : []mockHttpRequest {},
766766 expectedLogLines : []string {
767- "registered jfrog OIDC credentials for npm registry: jfrog.example.com" ,
767+ "registered jfrog OIDC credentials for npm registry: https:// jfrog.example.com" ,
768768 },
769769 urlsToAuthenticate : []string {
770770 "https://jfrog.example.com/some-package" ,
@@ -787,7 +787,7 @@ func TestOIDCURLsAreAuthenticated(t *testing.T) {
787787 },
788788 urlMocks : []mockHttpRequest {},
789789 expectedLogLines : []string {
790- "registered cloudsmith OIDC credentials for npm registry: cloudsmith.example.com" ,
790+ "registered cloudsmith OIDC credentials for npm registry: https:// cloudsmith.example.com" ,
791791 },
792792 urlsToAuthenticate : []string {
793793 "https://cloudsmith.example.com/some-package" ,
@@ -1441,3 +1441,54 @@ func TestPythonOIDCSimpleSuffixStripping(t *testing.T) {
14411441 reqB = handleRequestAndClose (handler , reqB , nil )
14421442 assertHasTokenAuth (t , reqB , "Bearer" , "__token_B__" , "feed-B request should use token B" )
14431443}
1444+
1445+ // TestNPMOIDCSameHostDifferentPaths verifies that two npm OIDC credentials on
1446+ // the same host with different URL paths do not collide — each request is
1447+ // authenticated with the credential whose path is the longest prefix match.
1448+ func TestNPMOIDCSameHostDifferentPaths (t * testing.T ) {
1449+ httpmock .Activate ()
1450+ defer httpmock .DeactivateAndReset ()
1451+
1452+ tenantA := "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
1453+ tenantB := "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
1454+ clientId := "87654321-4321-4321-4321-210987654321"
1455+
1456+ tokenUrl := "https://token.actions.example.com" //nolint:gosec // test URL
1457+ httpmock .RegisterResponder ("GET" , tokenUrl ,
1458+ httpmock .NewStringResponder (200 , `{"count":1,"value":"sometoken"}` ))
1459+
1460+ httpmock .RegisterResponder ("POST" , fmt .Sprintf ("https://login.microsoftonline.com/%s/oauth2/v2.0/token" , tenantA ),
1461+ httpmock .NewStringResponder (200 , `{"access_token":"__token_A__","expires_in":3600,"token_type":"Bearer"}` ))
1462+ httpmock .RegisterResponder ("POST" , fmt .Sprintf ("https://login.microsoftonline.com/%s/oauth2/v2.0/token" , tenantB ),
1463+ httpmock .NewStringResponder (200 , `{"access_token":"__token_B__","expires_in":3600,"token_type":"Bearer"}` ))
1464+
1465+ t .Setenv ("ACTIONS_ID_TOKEN_REQUEST_URL" , tokenUrl )
1466+ t .Setenv ("ACTIONS_ID_TOKEN_REQUEST_TOKEN" , "sometoken" )
1467+
1468+ creds := config.Credentials {
1469+ config.Credential {
1470+ "type" : "npm_registry" ,
1471+ "url" : "https://pkgs.example.com/org/feed-A" ,
1472+ "tenant-id" : tenantA ,
1473+ "client-id" : clientId ,
1474+ },
1475+ config.Credential {
1476+ "type" : "npm_registry" ,
1477+ "url" : "https://pkgs.example.com/org/feed-B" ,
1478+ "tenant-id" : tenantB ,
1479+ "client-id" : clientId ,
1480+ },
1481+ }
1482+
1483+ handler := NewNPMRegistryHandler (creds )
1484+
1485+ // Request to feed-A path should get token A
1486+ reqA := httptest .NewRequest ("GET" , "https://pkgs.example.com/org/feed-A/some-package" , nil )
1487+ reqA = handleRequestAndClose (handler , reqA , nil )
1488+ assertHasTokenAuth (t , reqA , "Bearer" , "__token_A__" , "feed-A should use token A" )
1489+
1490+ // Request to feed-B path should get token B
1491+ reqB := httptest .NewRequest ("GET" , "https://pkgs.example.com/org/feed-B/some-package" , nil )
1492+ reqB = handleRequestAndClose (handler , reqB , nil )
1493+ assertHasTokenAuth (t , reqB , "Bearer" , "__token_B__" , "feed-B should use token B" )
1494+ }
0 commit comments