Pub/sub topic call from Apigee X

Hi Team,

Please let me know how can we incorporate service account required to call pubsub inside proxy code itself along with service callout or publish message without the need of any json key.

i am looking for an alternative of adding the service account during deployment.

Right now i am trying to create a mock proxy which is making a service callout to the pubsub publish url , but the call throws a 404 not found error.

A quick response will be of great help.

Thanks!

Hey @Archie,

We’ve noticed your question hasn’t been answered yet, but we’ll keep it on our radar and reach out to others in the community to chime in. :wink:

Hey @Archie - the following should help:

  • I am not sure how you are currently orchestrating your CICD deployment processes, but references examples such as our Mavin Plugin (see more here: GitHub - apigee/apigee-deploy-maven-plugin) do support the usage of an access token via service account input (using the name of the service account as type string, not through a key)
  • A 404 exception does not typically indicate that an issue is AuthN/AuthZ specific, are you sure the project/topic/etc are all set correctly in your call-out? Are you using the PublishMessage policy, or are you manually orchestrating the call-out similar to the following: Dynamically set Service Account for an API Proxy - Apigee X

Thanks!
Matt

OK What I understand is that you would like an Apigee API proxy to publish a message to a pub/sub topic, but … you don’t want the Apigee API Proxy to be deployed with a Service Account, and you don’t want a downloaded service account key.

The problem as you have stated it, may be over-constrained.

Publishing a message to a Pub/Sub will require some sort of authentication. Of course you could turn it all off, allowing any caller to publish a message to a topic, but that seems like a Very Bad Idea. So I will rule that out as impractical.

What does that leave us with? Callers that publish a message to a pub/sub topic, either with the PublishMessage policy or with ServiceCallout (either works) . And actually , both of them result in the same “network call” on the wire; both of them will invoke the REST API. And since we are not “turning off” authentication (see above), both of them need an access token in the Authorization header.

So how do you get an Access Token?

If you deploy your API proxy with a specific service account, then you can embed the Authentication element inside your ServiceCallout or PublishMessage policy , and then the Apigee runtime will auto-generate an access token and inject it into the outgoing message to pubsub.googleapis.com . But this requires that your API proxy have a service account at deployment time.

That is probably the easiest / best way. but there are other options. I recorded a relevant screencast a little while ago on the various ways an Apigee proxy can get an access token to talk to a Cloud Run service. While it specifically discusses Cloud Run, the general principles apply to any remote service that requires Authentication. It would work the same with your PubSub topic.

The options are:

  • Direct (passthrough) - the caller of the Apigee proxy must provide a token
  • With Platform authentication - using the Authentication element I just described.
  • Impersonation - calling out to get a token from the iamcredentials endpoint. As with the Authentication element, this requires the proxy be deployed with a service account.
  • Using a Service Account key file - I think you said you wanted to avoid this too.

So … that’s what I mean by “I think your problem is over-constrained”. The way I interpreted what you wrote, you want to authenticate, but you don’t want to use a service account key file, and you don’t want to attach a service account to the proxy. I don’t think that is a solvable problem, if my understanding is correct!

Good luck.

Appreciate your effort @dchiesa1 .

So i understood that we have to mandatorily provide the service account during deployment of proxy in apigee X.

Can u help me with the code format :

1.Using service callout to call pubsub - without using json key. Below is my current setup. What i want to know is if i can give the service account detail somewhere here. If not, then what is possibly missing here.

<ServiceCallout continueOnError="false" enabled="false" name="SC-mock">
  <DisplayName>SC-mock</DisplayName>
  <Properties/>
  <Request>
    <Set>
      <Headers>
        <Header name="Content-Type">application/json</Header>
      </Headers>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <Payload contentType="application/json">{
           "customAttributes": {
            "is_transaction": "false"
        },
          "message" : {"data"}
      }</Payload>
    </Set>
  </Request>
  <Response>calloutResponse</Response>
  <HTTPTargetConnection>
    <Properties/>
    <Authentication>
    <GoogleAccessToken>
      <Scopes>
        <Scope>https://www.googleapis.com/auth/pubsub</Scope>
      </Scopes>
    </GoogleAccessToken>
  </Authentication>
  <SSLInfo>
    <Enabled>true</Enabled>
    <IgnoreValidationErrors>false</IgnoreValidationErrors>
  </SSLInfo>
  <URL>https://pubsuburl:publish</URL>
</HTTPTargetConnection>
</ServiceCallout>

2.Using publish message to call pubsub- without using json key

It’s not quite that strict. I think if you want to authenticate, then you need to provide some basis on which to authenticate. That can be one of the options I described. Providing a service account during deployment is one option.

When you use the Authentication element within ServiceCallout, the Apigee runtime implicitly uses the service account that you specified at the time you deployed the proxy. You do not specify the service account in the policy configuration. You specify it when you deploy the proxy.

If you want the policy to use a service account that is not implicitly derived, then use one of the other options I described in the list I provided in my previous reply.

Good luck!