in token-service/src/main/java/com/google/solutions/tokenservice/web/RuntimeEnvironment.java [76:195]
public RuntimeEnvironment() {
//
// Create a log adapter. We can't rely on injection as the adapter
// is request-scoped.
//
var logAdapter = new LogAdapter();
//
// Validate options.
//
var validClientIdHeaders = Set.of(
this.configuration.mtlsClientCertSpiffeIdHeader.getValue(),
this.configuration.mtlsClientCertDnsSansHeader.getValue(),
this.configuration.mtlsClientCertUriSansHeader.getValue(),
this.configuration.mtlsClientCertHashHeader.getValue());
if (!validClientIdHeaders.contains(this.configuration.mtlsClientIdHeader.getValue())) {
throw new RuntimeException(
String.format(
"The header '%s' cannot be used as client ID header. " +
"Use one of the following headers instead: %s.",
this.configuration.mtlsClientIdHeader.getValue(),
String.join(", ", validClientIdHeaders)));
}
if (isRunningOnCloudRun()) {
//
// Initialize using service account attached to AppEngine or Cloud Run.
//
try {
var applicationCredentials = GoogleCredentials.getApplicationDefault();
this.serviceAccount = new ServiceAccount(
new UserId(((ComputeEngineCredentials) applicationCredentials).getAccount()),
applicationCredentials);
logAdapter
.newInfoEntry(
LogEvents.RUNTIME_STARTUP,
String.format("Running as %s, version %s",
this.serviceAccount,
ApplicationVersion.VERSION_STRING))
.write();
}
catch (IOException e) {
logAdapter
.newErrorEntry(
LogEvents.RUNTIME_STARTUP,
"Failed to lookup instance metadata", e)
.write();
throw new RuntimeException("The runtime environment failed to initialize ", e);
}
}
else if (isDebugModeEnabled()) {
//
// Initialize using development settings and credential.
//
try {
var defaultCredentials = GoogleCredentials.getApplicationDefault();
var impersonateServiceAccount = System.getProperty(CONFIG_IMPERSONATE_SA);
if (impersonateServiceAccount != null && !impersonateServiceAccount.isEmpty()) {
//
// Use the application default credentials (ADC) to impersonate a
// service account. This can be used when using user credentials as ADC.
//
var impersonatedCredentials = ImpersonatedCredentials.create(
defaultCredentials,
impersonateServiceAccount,
null,
Stream.of(ServiceAccount.OAUTH_SCOPE)
.distinct()
.collect(Collectors.toList()),
0);
//
// If we lack impersonation permissions, ImpersonatedCredentials
// will keep retrying until the call timeout expires. The effect
// is that the application seems hung.
//
// To prevent this from happening, force a refresh here. If the
// refresh fails, fail application startup.
//
impersonatedCredentials.refresh();
this.serviceAccount = new ServiceAccount(
new UserId(impersonateServiceAccount),
impersonatedCredentials);
}
else if (defaultCredentials instanceof ServiceAccountCredentials) {
//
// Use ADC as-is.
//
this.serviceAccount = new ServiceAccount(
new UserId(((ServiceAccountCredentials) defaultCredentials).getServiceAccountUser()),
defaultCredentials);
}
else {
throw new RuntimeException(String.format(
"You're using user credentials as application default "
+ "credentials (ADC). Use -D%s=<service-account-email> to impersonate "
+ "a service account during development",
CONFIG_IMPERSONATE_SA));
}
}
catch (IOException e) {
throw new RuntimeException("Failed to lookup application credentials", e);
}
logAdapter
.newWarningEntry(
LogEvents.RUNTIME_STARTUP,
String.format("Running in development mode as %s", this.serviceAccount))
.write();
}
else {
throw new RuntimeException(
"Application is not running on Cloud Run and debug mode is disabled. Aborting startup");
}
}