Search code examples
google-cloud-platformgoogle-iamgoogle-cloud-iam

Getting a 403 Forbidden error when attempting to publish to GCP from a Spring Boot application


I am attempting to utilize PubSub in my Spring Boot application to send messages to another service any time an item is updated or created. I have been simply trying to test the functionality of publishing a test message before setting it up for what I will actually need it for. However I am having some difficulty linking my application up to GCP. Every time I attempt to publish I receive a 403 Forbidden error as seen below.

Caused by: com.google.api.client.http.HttpResponseException: 403 Forbidden
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/[email protected]:generateAccessToken
{
  "error": {
    "code": 403,
    "message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
    "errors": [
      {
        "message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
        "domain": "global",
        "reason": "forbidden"
      }
    ],
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "IAM_PERMISSION_DENIED",
        "domain": "iam.googleapis.com",
        "metadata": {
          "permission": "iam.serviceAccounts.getAccessToken"
        }
      }
    ]
  }
}

This error comes through about 10 minutes after I attempt the publish, when the request times out. I have tried this out using a service account and topic from my colleague's project that has been able to successfully publish and subscribe to GCP PubSub but I still receive the same error.

My code is nearly identical to my colleague's project with my publishing present in my @RestController as such:

@Autowired
    PubSubTemplate pubSubTemplate;
    @GetMapping("/postMessage")
    public String publish(@RequestParam("topicName") String topicName,
                          @RequestParam("message") String message) {
        pubSubTemplate.publish(topicName, message);


        return "Messages published asynchronously; status unknown.";
    }

And my subscription code in it's own PubSubConfig file as such:

@Slf4j
@Configuration
public class PubSubConfiguration {

    @Bean
    public MessageChannel pubSubInputChannel() { return new PublishSubscribeChannel(); }

    @Bean
    public PubSubInboundChannelAdapter messageChannelAdapter(
            @Qualifier("pubSubInputChannel") MessageChannel inputChannel,
            PubSubTemplate pubSubTemplate) {
        PubSubInboundChannelAdapter adapter =
                new PubSubInboundChannelAdapter(pubSubTemplate, "test_pullsub");
        adapter.setOutputChannel(inputChannel);
        adapter.setAckMode(AckMode.MANUAL);
        adapter.setPayloadType(String.class);
        return adapter;
    }

    @ServiceActivator(inputChannel = "pubSubInputChannel")
    public void messageReceiver(String payload,
                                @Header(GcpPubSubHeaders.ORIGINAL_MESSAGE) BasicAcknowledgeablePubsubMessage message) {
        log.info("Message arrived via an inbound channel adapter from sub-one! Payload: " + payload);
        message.ack();
    }
}

I am triggering the publish event by sending a get request in Postman to the URL http://localhost:8080/cloc/postMessage?topicName=test-topic&message=Hello with the application running locally.

I am able to reach a breakpoint set at pubSubTemplate.publish(topicName, message); but after that the message is unable to go through.

I have been able to successfully publish a message via the Google CLI using the command gcloud pubsub topics publish test-topic --message="Hello World" So I don't believe it is a permission issue with the service account.

If needed the imports I am using in my build.gradle file are as such:

bomImport platform('io.pivotal.spring.cloud:spring-cloud-services-dependencies:2.4.1')
bomImport platform (group: 'com.google.cloud', name: 'spring-cloud-gcp-dependencies', version: '3.2.1')
implementation 'org.springframework.cloud:spring-cloud-gcp-starter-pubsub:1.2.5.RELEASE'
implementation platform('com.google.cloud:libraries-bom:26.10.0')
implementation 'com.google.cloud:google-cloud-pubsub'

Any help would be greatly appreciated.


Solution

  • The problem is that you are missing the permission iam.serviceAccounts.getAccessToken.

    Add the IAM roles/iam.serviceAccountTokenCreator (Service Account Token Creator) to the service account receiving this error.

    Roles for managing and impersonating service accounts