Skip to content

Commit 28df732

Browse files
committed
feat: Add additional credential info for ADC Credentials
1 parent 1669dc8 commit 28df732

10 files changed

+79
-2
lines changed

oauth2_http/java/com/google/auth/oauth2/AppEngineCredentials.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ private void init() throws IOException {
125125
this.signForApp = serviceClass.getMethod(SIGN_FOR_APP_METHOD, byte[].class);
126126
Class<?> signingResultClass = forName(SIGNING_RESULT_CLASS);
127127
this.getSignature = signingResultClass.getMethod(GET_SIGNATURE_METHOD);
128+
this.type = "App Engine Credentials";
128129
} catch (ClassNotFoundException
129130
| NoSuchMethodException
130131
| IllegalAccessException

oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ private ComputeEngineCredentials(ComputeEngineCredentials.Builder builder) {
220220
}
221221
this.transport = builder.getGoogleAuthTransport();
222222
this.bindingEnforcement = builder.getBindingEnforcement();
223+
this.type = "Compute Engine Credentials";
223224
}
224225

225226
@Override
@@ -691,6 +692,7 @@ public String getAccount() {
691692
if (serviceAccountEmail == null) {
692693
try {
693694
serviceAccountEmail = getDefaultServiceAccount();
695+
this.principal = serviceAccountEmail;
694696
} catch (IOException ex) {
695697
throw new RuntimeException("Failed to get service account", ex);
696698
}

oauth2_http/java/com/google/auth/oauth2/DefaultCredentialsProvider.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,10 @@ private final GoogleCredentials getDefaultCredentialsUnsynchronized(
145145
throw new IOException("File does not exist.");
146146
}
147147
credentialsStream = readStream(credentialsFile);
148-
credentials = GoogleCredentials.fromStream(credentialsStream, transportFactory);
148+
credentials =
149+
GoogleCredentials.fromStream(credentialsStream, transportFactory)
150+
.withSource(
151+
String.format("Env Var %s set to %s", CREDENTIAL_ENV_VAR, credentialsPath));
149152
} catch (IOException e) {
150153
// Although it is also the cause, the message of the caught exception can have very
151154
// important information for diagnosing errors, so include its message in the
@@ -176,7 +179,11 @@ private final GoogleCredentials getDefaultCredentialsUnsynchronized(
176179
"Attempting to load credentials from well known file: %s",
177180
wellKnownFileLocation.getCanonicalPath()));
178181
credentialsStream = readStream(wellKnownFileLocation);
179-
credentials = GoogleCredentials.fromStream(credentialsStream, transportFactory);
182+
credentials =
183+
GoogleCredentials.fromStream(credentialsStream, transportFactory)
184+
.withSource(
185+
String.format(
186+
"Well Known File at %s", wellKnownFileLocation.getCanonicalPath()));
180187
}
181188
} catch (IOException e) {
182189
throw new IOException(
@@ -210,6 +217,14 @@ private final GoogleCredentials getDefaultCredentialsUnsynchronized(
210217
if (credentials == null) {
211218
LOGGER.log(Level.FINE, "Attempting to load credentials from GCE");
212219
credentials = tryGetComputeCredentials(transportFactory);
220+
// tryGetComputeCredentials can return a null value. This check won't set the source
221+
// if the ComputeEngineCredentials fails (prevents a NPE)
222+
if (credentials != null) {
223+
credentials =
224+
credentials.withSource(
225+
String.format(
226+
"Metadata Server URL set to %s", System.getenv(GCE_METADATA_HOST_ENV_VAR)));
227+
}
213228
}
214229

215230
if (credentials != null) {

oauth2_http/java/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentials.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ private ExternalAccountAuthorizedUserCredentials(Builder builder) {
117117
this.clientId = builder.clientId;
118118
this.clientSecret = builder.clientSecret;
119119

120+
this.type = "External Account Authorized User Credentials";
121+
120122
Preconditions.checkState(
121123
getAccessToken() != null || canRefresh(),
122124
"ExternalAccountAuthorizedUserCredentials must be initialized with "

oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ protected ExternalAccountCredentials(
214214
}
215215

216216
this.metricsHandler = new ExternalAccountMetricsHandler(this);
217+
this.type = "External Account Credentials";
217218
}
218219

219220
/**

oauth2_http/java/com/google/auth/oauth2/GdchCredentials.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public class GdchCredentials extends GoogleCredentials {
9696
this.caCertPath = builder.caCertPath;
9797
this.apiAudience = builder.apiAudience;
9898
this.lifetime = builder.lifetime;
99+
this.type = "GDCH Credentials";
99100
}
100101

101102
/**

oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.google.common.annotations.VisibleForTesting;
4141
import com.google.common.base.MoreObjects;
4242
import com.google.common.base.MoreObjects.ToStringHelper;
43+
import com.google.common.base.Strings;
4344
import com.google.common.collect.ImmutableList;
4445
import com.google.errorprone.annotations.CanIgnoreReturnValue;
4546
import java.io.IOException;
@@ -64,6 +65,14 @@ public class GoogleCredentials extends OAuth2Credentials implements QuotaProject
6465
static final String SERVICE_ACCOUNT_FILE_TYPE = "service_account";
6566
static final String GDCH_SERVICE_ACCOUNT_FILE_TYPE = "gdch_service_account";
6667

68+
/* The following package-private fields provide additional info for errors message */
69+
// Source of the credential (e.g. env var value or well know file location)
70+
String source;
71+
// User-friendly name of actual Credential class
72+
String type;
73+
// Identity of the credential (not all credentials will have this)
74+
String principal;
75+
6776
private final String universeDomain;
6877
private final boolean isExplicitUniverseDomain;
6978

@@ -359,6 +368,8 @@ protected GoogleCredentials(Builder builder) {
359368
this.universeDomain = builder.getUniverseDomain();
360369
this.isExplicitUniverseDomain = true;
361370
}
371+
372+
this.source = builder.source;
362373
}
363374

364375
/**
@@ -497,9 +508,40 @@ public GoogleCredentials createDelegated(String user) {
497508
return this;
498509
}
499510

511+
/**
512+
* Internal method meant to help provide information for how certain Credential objects loaded by
513+
* ADC were initialized
514+
*/
515+
GoogleCredentials withSource(String source) {
516+
return toBuilder().setSource(source).build();
517+
}
518+
519+
/**
520+
* Provides additional information regarding credential initialization source - Initialized via
521+
* the GOOGLE_APPLICATION_CREDENTIALS env var or well known file type - The type of credential
522+
* created principal - Identity used for the credential These fields are populated on a
523+
* best-effort basis and may be null or missing
524+
*
525+
* @return Map of information regarding how the Credential was initialized
526+
*/
527+
public Map<String, String> getCredentialInfo() {
528+
Map<String, String> infoMap = new HashMap<>();
529+
if (!Strings.isNullOrEmpty(source)) {
530+
infoMap.put("Credential Source", source);
531+
}
532+
if (!Strings.isNullOrEmpty(type)) {
533+
infoMap.put("Credential Type", type);
534+
}
535+
if (!Strings.isNullOrEmpty(principal)) {
536+
infoMap.put("Principal", principal);
537+
}
538+
return infoMap;
539+
}
540+
500541
public static class Builder extends OAuth2Credentials.Builder {
501542
@Nullable protected String quotaProjectId;
502543
@Nullable protected String universeDomain;
544+
String source;
503545

504546
protected Builder() {}
505547

@@ -541,6 +583,11 @@ public String getUniverseDomain() {
541583
return this.universeDomain;
542584
}
543585

586+
Builder setSource(String source) {
587+
this.source = source;
588+
return this;
589+
}
590+
544591
@Override
545592
@CanIgnoreReturnValue
546593
public Builder setAccessToken(AccessToken token) {

oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ private ImpersonatedCredentials(Builder builder) throws IOException {
480480
throw new IllegalStateException("lifetime must be less than or equal to 43200");
481481
}
482482

483+
this.type = "Impersonated Credentials";
484+
this.principal = builder.targetPrincipal;
485+
483486
// Do not expect explicit universe domain, throw exception if the explicit universe domain
484487
// does not match the source credential.
485488
// Do nothing if it matches the source credential

oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ public class ServiceAccountCredentials extends GoogleCredentials
150150
this.lifetime = builder.lifetime;
151151
this.useJwtAccessWithScope = builder.useJwtAccessWithScope;
152152
this.defaultRetriesEnabled = builder.defaultRetriesEnabled;
153+
this.type = "Service Account Credentials";
154+
this.principal = builder.clientEmail;
153155
}
154156

155157
/**

oauth2_http/java/com/google/auth/oauth2/UserCredentials.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ private UserCredentials(Builder builder) {
9696
this.tokenServerUri =
9797
(builder.tokenServerUri == null) ? OAuth2Utils.TOKEN_SERVER_URI : builder.tokenServerUri;
9898
this.transportFactoryClassName = this.transportFactory.getClass().getName();
99+
100+
this.type = "User Credentials";
101+
99102
Preconditions.checkState(
100103
builder.getAccessToken() != null || builder.refreshToken != null,
101104
"Either accessToken or refreshToken must not be null");

0 commit comments

Comments
 (0)