Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-17423

Google Pubsub Authentication

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 3.14.0
    • 4.x
    • camel-google-pubsub
    • None
    • Unknown

    Description

      I work for a cloud service provider that includes an integration application that uses Camel for the core operations of an integration. Because of factors such as industry regulation and customer InfoSec policies/requirements, placing access keys within an application, its filesystem, associated direct data stores, etc. is not permitted. This requires credentials to be provided by a lookup service that provides decrypted values to an application, exposed through variables. While our SaaS offering does provide an identity hub that integrates with customer IdPs, these integration applications will not use those as credential stores, directly.

      With that, the serviceAccountKey would need to be provided via a variable, environment variable, etc., where the JSON string would be passed into that field value.

      I've made a modification to allow for this by modifying the getCredentialsProvider method of the GooglePubsubCompenent.java file of the camel-google-pubsub component. This would respond to a prefix and then take the value from the passed parameter and use it for the credentials.

      GooglePubsubComponent.java
      private CredentialsProvider getCredentialsProvider(GooglePubsubEndpoint endpoint) throws IOException {
              CredentialsProvider credentialsProvider;
      
              // The original method logic
              //        if (endpoint.isAuthenticate()) {
              //            credentialsProvider = FixedCredentialsProvider.create(ObjectHelper.isEmpty(endpoint.getServiceAccountKey())
              //                    ? GoogleCredentials.getApplicationDefault() : ServiceAccountCredentials.fromStream(ResourceHelper
              //                            .resolveMandatoryResourceAsInputStream(getCamelContext(), endpoint.getServiceAccountKey())));
              //        } else {
              //            credentialsProvider = NoCredentialsProvider.create();
              //        }
      
              // Modified for JSON input
              if (endpoint.isAuthenticate()) {
                  if (ObjectHelper.isEmpty(endpoint.getServiceAccountKey())) {
                      credentialsProvider = FixedCredentialsProvider.create(GoogleCredentials.getApplicationDefault());
                  } else if (endpoint.getServiceAccountKey().startsWith("json:")) {  // <- For the JSON string
                      credentialsProvider = FixedCredentialsProvider.create(ServiceAccountCredentials.fromStream(
                          new ByteArrayInputStream(Base64.getUrlDecoder().decode(endpoint.getServiceAccountKey().substring(5)))));
                  } else {
                      credentialsProvider = FixedCredentialsProvider.create(ServiceAccountCredentials.fromStream(
                          ResourceHelper.resolveResourceAsInputStream(getCamelContext(), endpoint.getServiceAccountKey())));
                  }
              } else {
                  credentialsProvider = NoCredentialsProvider.create();
              }
      
              return credentialsProvider;
      }
      

      This would then allows for the component to be defined with the serviceAccountKey as below. The JSON string would need to be encoded via Base64 to allow the internal encoded key to be properly passed through.

      GcpPubsubRoute.java
      @Override
      public void configure() throws Exception {
          from("direct:gcpTest").id("gcpTest")
              .setHeader(GooglePubsubConstants.ATTRIBUTES,
                  constant(Map.of("testKey1", "testValue1", "testKey2", "testValue2")))
              .setBody(simple("{\"someKey\": \"someValue\"}"))
              .toD("google-pubsub:{{PROJECT_NAME}}:{{TOPIC_NAME}}?serviceAccountKey=json:{{BASE64_CREDS}}")
              .log("Message ID: ${header." + GooglePubsubConstants.MESSAGE_ID + "}");
      }
      

      I understand the concern around using an environment variable to pass credentials to a container. There is, however, a common pattern of cloud providers that expose external configuration to containers through environment variables.

      Attachments

        Activity

          People

            Unassigned Unassigned
            rarnhart Rob Arnhart
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated: