public static ApplicationRuntime detect()

in sources/src/main/java/com/google/solutions/jitaccess/ApplicationRuntime.java [108:219]


  public static ApplicationRuntime detect(
    @NotNull Set<String> requiredOauthScopes
  ) throws IOException {
    if (isRunningOnAppEngine() || isRunningOnCloudRun()) {
      //
      // Initialize using service account attached to AppEngine or Cloud Run.
      //
      var projectMetadata = getMetadata().parseAs(GenericData.class);
      var projectId = (String) projectMetadata.get("projectId");
      var projectNumber = projectMetadata.get("numericProjectId").toString();

      var defaultCredentials = (ComputeEngineCredentials)GoogleCredentials.getApplicationDefault();
      var applicationPrincipal = ServiceAccountId
        .parse(ServiceAccountId.TYPE + ":" + defaultCredentials.getAccount())
        .orElseThrow(() -> new IllegalArgumentException(
          String.format("'%s' is not a valid service account email address",
            defaultCredentials.getAccount())));

      GoogleCredentials applicationCredentials;
      if (defaultCredentials.getScopes().containsAll(requiredOauthScopes)) {
        //
        // Default credential has all the right scopes, use it as-is.
        //
        applicationCredentials = defaultCredentials;
      }
      else {
        //
        // Extend the set of scopes to include required non-cloud APIs by
        // letting the service account impersonate itself.
        //
        applicationCredentials = ImpersonatedCredentials.create(
          defaultCredentials,
          applicationPrincipal.value(),
          null,
          requiredOauthScopes.stream().toList(),
          0);
      }

      return new ApplicationRuntime(
        isRunningOnAppEngine() ? Type.APPENGINE : Type.CLOUDRUN,
        new ProjectId(projectId),
        projectNumber,
        applicationCredentials,
        applicationPrincipal);
    }
    else if (isDebugModeEnabled()) {
      //
      // Initialize using development settings and credential.
      //
      var defaultCredentials = GoogleCredentials.getApplicationDefault();

      var impersonateServiceAccount = ServiceAccountId.parse(
        ServiceAccountId.TYPE + ":" + System.getProperty(CONFIG_IMPERSONATE_SA));

      GoogleCredentials applicationCredentials;
      ServiceAccountId applicationPrincipal;
      if (impersonateServiceAccount.isPresent()) {
        //
        // Use the application default credentials (ADC) to impersonate a
        // service account. This step is necessary to ensure we have a
        // credential for the right set of scopes, and that we're not running
        // with end-user credentials.
        //
        applicationCredentials = ImpersonatedCredentials.create(
          defaultCredentials,
          impersonateServiceAccount.get().value(),
          null,
          requiredOauthScopes.stream().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.
        //
        applicationCredentials.refresh();
        applicationPrincipal = impersonateServiceAccount.get();
      }
      else if (defaultCredentials instanceof ServiceAccountCredentials saCredentials) {
        //
        // Use ADC as-is.
        //
        applicationCredentials = defaultCredentials;
        applicationPrincipal = ServiceAccountId
          .parse(saCredentials.getServiceAccountUser())
          .orElseThrow(() -> new RuntimeException(String.format(
            "The email '%s' is not a valid service account email address",
            saCredentials.getServiceAccountUser())));
      }
      else {
        throw new IllegalArgumentException(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));
      }

      return new ApplicationRuntime(
        Type.DEVELOPMENT,
        new ProjectId(System.getProperty(CONFIG_PROJECT, "dev")),
        "0",
        applicationCredentials,
        applicationPrincipal);
    }
    else {
      throw new RuntimeException(
        "Application is not running on AppEngine or Cloud Run, and debug mode is disabled. Aborting startup");
    }
  }