public RuntimeEnvironment()

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");
    }
  }