Skip to content

Commit 84c11d0

Browse files
committed
Update oidc provider detection
Signed-off-by: Appu Goundan <[email protected]>
1 parent 8bd98de commit 84c11d0

File tree

9 files changed

+108
-26
lines changed

9 files changed

+108
-26
lines changed

sigstore-cli/src/main/java/dev/sigstore/cli/TokenStringOidcClient.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import dev.sigstore.oidc.client.OidcException;
2323
import dev.sigstore.oidc.client.OidcToken;
2424
import java.io.IOException;
25+
import java.util.Map;
2526

2627
public class TokenStringOidcClient implements OidcClient {
2728

@@ -32,12 +33,12 @@ public TokenStringOidcClient(String idToken) {
3233
}
3334

3435
@Override
35-
public boolean isEnabled() {
36+
public boolean isEnabled(Map<String, String> env) {
3637
return true;
3738
}
3839

3940
@Override
40-
public OidcToken getIDToken() throws OidcException {
41+
public OidcToken getIDToken(Map<String, String> env) throws OidcException {
4142
try {
4243
var jws = JsonWebSignature.parse(new GsonFactory(), idToken);
4344
return ImmutableOidcToken.builder()

sigstore-java/src/main/java/dev/sigstore/oidc/client/GithubActionsOidcClient.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import dev.sigstore.http.ImmutableHttpParams;
2626
import io.grpc.Internal;
2727
import java.io.IOException;
28+
import java.util.Map;
2829
import java.util.logging.Logger;
2930

3031
/**
@@ -35,9 +36,9 @@ public class GithubActionsOidcClient implements OidcClient {
3536

3637
private static final Logger log = Logger.getLogger(GithubActionsOidcClient.class.getName());
3738

38-
private static final String GITHUB_ACTIONS_KEY = "GITHUB_ACTIONS";
39-
private static final String REQUEST_TOKEN_KEY = "ACTIONS_ID_TOKEN_REQUEST_TOKEN";
40-
private static final String REQUEST_URL_KEY = "ACTIONS_ID_TOKEN_REQUEST_URL";
39+
static final String GITHUB_ACTIONS_KEY = "GITHUB_ACTIONS";
40+
static final String REQUEST_TOKEN_KEY = "ACTIONS_ID_TOKEN_REQUEST_TOKEN";
41+
static final String REQUEST_URL_KEY = "ACTIONS_ID_TOKEN_REQUEST_URL";
4142

4243
private static final String DEFAULT_AUDIENCE = "sigstore";
4344

@@ -75,19 +76,25 @@ public GithubActionsOidcClient build() {
7576
}
7677

7778
@Override
78-
public boolean isEnabled() {
79-
var githubActions = System.getenv(GITHUB_ACTIONS_KEY);
79+
public boolean isEnabled(Map<String, String> env) {
80+
var githubActions = env.get(GITHUB_ACTIONS_KEY);
8081
if (githubActions == null || githubActions.isEmpty()) {
8182
log.fine("Github env not detected: skipping github actions oidc");
8283
return false;
8384
}
85+
var bearer = env.get(REQUEST_TOKEN_KEY);
86+
var urlBase = env.get(REQUEST_URL_KEY);
87+
if (bearer == null || bearer.isEmpty() || urlBase == null || urlBase.isEmpty()) {
88+
log.info("Github env detected, but github idtoken not found: skipping github actions oidc");
89+
return false;
90+
}
8491
return true;
8592
}
8693

8794
@Override
88-
public OidcToken getIDToken() throws OidcException {
89-
var bearer = System.getenv(REQUEST_TOKEN_KEY);
90-
var urlBase = System.getenv(REQUEST_URL_KEY);
95+
public OidcToken getIDToken(Map<String, String> env) throws OidcException {
96+
var bearer = env.get(REQUEST_TOKEN_KEY);
97+
var urlBase = env.get(REQUEST_URL_KEY);
9198
if (bearer == null) {
9299
throw new OidcException(
93100
"Could not get github actions environment variable '" + REQUEST_TOKEN_KEY + "'");

sigstore-java/src/main/java/dev/sigstore/oidc/client/OidcClient.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@
1515
*/
1616
package dev.sigstore.oidc.client;
1717

18+
import java.util.Map;
19+
1820
public interface OidcClient {
1921

2022
/**
2123
* Determine if this client can be used in the current environment. For example, we can ignore
2224
* Oidc Clients that are scoped to a specific CI environment
2325
*
26+
* @param env the configured system environment
2427
* @return true if we should use credentials from this client
2528
*/
26-
boolean isEnabled();
29+
boolean isEnabled(Map<String, String> env);
2730

28-
OidcToken getIDToken() throws OidcException;
31+
OidcToken getIDToken(Map<String, String> env) throws OidcException;
2932
}

sigstore-java/src/main/java/dev/sigstore/oidc/client/OidcClients.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@
1616
package dev.sigstore.oidc.client;
1717

1818
import com.google.common.collect.ImmutableList;
19+
import java.util.Map;
20+
import java.util.logging.Logger;
1921

2022
/** An ordered list of oidc clients to use when looking for credentials. */
2123
public class OidcClients {
2224

25+
private static final Logger log = Logger.getLogger(OidcClients.class.getName());
26+
2327
public static final OidcClients PUBLIC_GOOD =
2428
of(GithubActionsOidcClient.builder().build(), WebOidcClient.builder().build());
2529

@@ -29,13 +33,15 @@ public class OidcClients {
2933
WebOidcClient.builder().setIssuer(WebOidcClient.STAGING_DEX_ISSUER).build());
3034

3135
private final ImmutableList<OidcClient> clients;
36+
private final Map<String, String> env;
3237

3338
public static OidcClients of(OidcClient... clients) {
34-
return new OidcClients(ImmutableList.copyOf(clients));
39+
return new OidcClients(ImmutableList.copyOf(clients), System.getenv());
3540
}
3641

37-
private OidcClients(ImmutableList<OidcClient> clients) {
42+
private OidcClients(ImmutableList<OidcClient> clients, Map<String, String> env) {
3843
this.clients = clients;
44+
this.env = env;
3945
}
4046

4147
/**
@@ -47,10 +53,12 @@ private OidcClients(ImmutableList<OidcClient> clients) {
4753
*/
4854
public OidcToken getIDToken() throws OidcException {
4955
for (var client : clients) {
50-
if (client.isEnabled()) {
51-
return client.getIDToken();
56+
if (client.isEnabled(env)) {
57+
return client.getIDToken(env);
5258
}
5359
}
60+
log.info(
61+
"Could not find an oidc provider, if you are in CI make sure the token is available to the sigstore signing process");
5462
throw new OidcException("Could not find an oidc provider");
5563
}
5664
}

sigstore-java/src/main/java/dev/sigstore/oidc/client/WebOidcClient.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@
3838
import java.io.IOException;
3939
import java.util.Arrays;
4040
import java.util.Locale;
41+
import java.util.Map;
42+
import java.util.logging.Logger;
4143

4244
/**
4345
* A client to obtain oidc tokens from an oauth provider via web workflow for use with sigstore. By
4446
* default this client is configued to use the public sigstore dex instance.
4547
*/
4648
public class WebOidcClient implements OidcClient {
49+
private static final Logger log = Logger.getLogger(WebOidcClient.class.getName());
50+
4751
public static final String PUBLIC_DEX_ISSUER = "https://oauth2.sigstore.dev/auth";
4852
public static final String STAGING_DEX_ISSUER = "https://oauth2.sigstage.dev/auth";
4953

@@ -112,12 +116,13 @@ public WebOidcClient build() {
112116
}
113117
}
114118

115-
/**
116-
* This provider is always enabled by default, however it should be lower priority over other
117-
* providers which obtain ambient credentials.
118-
*/
119+
/** This provider is usually enabled unless we're in CI. */
119120
@Override
120-
public boolean isEnabled() {
121+
public boolean isEnabled(Map<String, String> env) {
122+
if ("true".equalsIgnoreCase(env.get("CI"))) {
123+
log.info("Skipping browser based oidc provider because CI detected");
124+
return false;
125+
}
121126
return true;
122127
}
123128

@@ -128,7 +133,7 @@ public boolean isEnabled() {
128133
* @throws OidcException if an error occurs doing the authorization flow
129134
*/
130135
@Override
131-
public OidcToken getIDToken() throws OidcException {
136+
public OidcToken getIDToken(Map<String, String> env) throws OidcException {
132137
JsonFactory jsonFactory = new GsonFactory();
133138
HttpTransport httpTransport = HttpClients.newHttpTransport(httpParams);
134139
DataStoreFactory memStoreFactory = new MemoryDataStoreFactory();

sigstore-java/src/test/java/dev/sigstore/KeylessSignerTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ public void sign_passGithubOidcCheck() throws Exception {
129129
// silly way to get the right oidc identity to make sure our simple matcher works
130130
var jws =
131131
JsonWebSignature.parse(
132-
new GsonFactory(), GithubActionsOidcClient.builder().build().getIDToken().getIdToken());
132+
new GsonFactory(),
133+
GithubActionsOidcClient.builder().build().getIDToken(System.getenv()).getIdToken());
133134
var expectedGithubSubject = jws.getPayload().getSubject();
134135
var signer =
135136
KeylessSigner.builder()

sigstore-java/src/test/java/dev/sigstore/oidc/client/GithubActionsOidcClientTest.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,56 @@
1717

1818
import dev.sigstore.testkit.annotations.EnabledIfOidcExists;
1919
import dev.sigstore.testkit.annotations.OidcProviderType;
20+
import io.github.netmikey.logunit.api.LogCapturer;
21+
import java.util.Map;
2022
import org.junit.jupiter.api.Assertions;
2123
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.api.extension.RegisterExtension;
25+
import org.slf4j.event.Level;
2226

2327
public class GithubActionsOidcClientTest {
2428

29+
@RegisterExtension
30+
LogCapturer logs =
31+
LogCapturer.create().captureForType(GithubActionsOidcClient.class, Level.DEBUG);
32+
2533
@Test
2634
@EnabledIfOidcExists(provider = OidcProviderType.GITHUB)
2735
public void getToken() throws OidcException {
2836
var client = GithubActionsOidcClient.builder().build();
29-
var token = client.getIDToken();
37+
var token = client.getIDToken(System.getenv());
3038

3139
Assertions.assertNotNull(token.getSubjectAlternativeName());
3240
Assertions.assertNotNull(token.getIdToken());
3341
}
42+
43+
@Test
44+
public void isEnabled_github() {
45+
var client = GithubActionsOidcClient.builder().build();
46+
var env =
47+
Map.of(
48+
GithubActionsOidcClient.GITHUB_ACTIONS_KEY,
49+
"ignored",
50+
GithubActionsOidcClient.REQUEST_TOKEN_KEY,
51+
"ignored",
52+
GithubActionsOidcClient.REQUEST_URL_KEY,
53+
"ignored");
54+
Assertions.assertTrue(client.isEnabled(env));
55+
}
56+
57+
@Test
58+
public void isEnabled_githubButNoTokenInfo() {
59+
var client = GithubActionsOidcClient.builder().build();
60+
var env = Map.of(GithubActionsOidcClient.GITHUB_ACTIONS_KEY, "ignored");
61+
Assertions.assertFalse(client.isEnabled(env));
62+
logs.assertContains(
63+
"Github env detected, but github idtoken not found: skipping github actions oidc");
64+
}
65+
66+
@Test
67+
public void isEnabled_notGithub() {
68+
var client = GithubActionsOidcClient.builder().build();
69+
Assertions.assertFalse(client.isEnabled(Map.of()));
70+
logs.assertContains("Github env not detected: skipping github actions oidc");
71+
}
3472
}

sigstore-java/src/test/java/dev/sigstore/oidc/client/WebOidcClientTest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,21 @@
1717

1818
import com.gargoylesoftware.htmlunit.WebClient;
1919
import dev.sigstore.testing.MockOAuth2ServerExtension;
20+
import io.github.netmikey.logunit.api.LogCapturer;
21+
import java.util.Map;
2022
import org.junit.jupiter.api.Assertions;
2123
import org.junit.jupiter.api.Test;
2224
import org.junit.jupiter.api.extension.RegisterExtension;
25+
import org.slf4j.event.Level;
2326

2427
public class WebOidcClientTest {
2528

2629
@RegisterExtension
2730
private static final MockOAuth2ServerExtension server = new MockOAuth2ServerExtension();
2831

32+
@RegisterExtension
33+
LogCapturer logs = LogCapturer.create().captureForType(WebOidcClient.class, Level.DEBUG);
34+
2935
@Test
3036
public void testAuthFlow() throws OidcException {
3137
try (var webClient = new WebClient()) {
@@ -35,9 +41,22 @@ public void testAuthFlow() throws OidcException {
3541
.setBrowser(webClient::getPage)
3642
.build();
3743

38-
var eid = oidcClient.getIDToken();
44+
var eid = oidcClient.getIDToken(System.getenv());
3945
Assertions.assertEquals(
4046
MockOAuth2ServerExtension.DEFAULT_CONFIGURED_EMAIL, eid.getSubjectAlternativeName());
4147
}
4248
}
49+
50+
@Test
51+
public void isEnabled_CI() {
52+
var client = WebOidcClient.builder().build();
53+
Assertions.assertFalse(client.isEnabled(Map.of("CI", "true")));
54+
logs.assertContains("Skipping browser based oidc provider because CI detected");
55+
}
56+
57+
@Test
58+
public void isEnabled_notCI() {
59+
var client = WebOidcClient.builder().build();
60+
Assertions.assertTrue(client.isEnabled(Map.of("CI", "false")));
61+
}
4362
}

sigstore-java/src/test/java/dev/sigstore/testing/MockOAuth2ServerExtension.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public OidcToken getOidcToken() throws OidcException {
7070
.setBrowser(webClient::getPage)
7171
.build();
7272

73-
return oidcClient.getIDToken();
73+
return oidcClient.getIDToken(System.getenv());
7474
}
7575
}
7676

0 commit comments

Comments
 (0)