Triggering from Pub/Sub push

You can use Pub/Sub to push messages to the endpoint of your Cloud Run service, which are subsequently delivered to containers as HTTP requests. You should process the message and then return a response when finished.

Leveraging service accounts and IAM permissions, you can securely and privately use Pub/Sub with Cloud Run, without having to expose your Cloud Run service publicly. Only the Pub/Sub subscription that you have set up is able to invoke your service.

Possible use cases include:

This page shows how to enable your service to securely process messages pushed from a Pub/Sub subscription in the same Google Cloud project.

To integrate your service with Pub/Sub,

  • Create a Pub/Sub topic.
  • Add code in your Cloud Run service to respond to the Pub/Sub messages sent to the topic you created.
  • Create a service account with the required permissions.
  • Create a Pub/Sub subscription and associate it with the service account. This subscription will send to your service any message that is published to the topic.

Before you start

If you haven't done so already, set up your environment as described in the setup page for Cloud Run or the setup page for Cloud Run for Anthos on Google Cloud. You'll need to use the gcloud command line and a Google Cloud project to deploy your Cloud Run service to.

Adding code to handle messages from Pub/Sub

Your service must extract the message from the request and return an expected success code. The following snippets for selected languages (you can use any language) show how to do this for a simple Hello World message:

Node.js'/', (req, res) => {
  if (!req.body) {
    const msg = 'no Pub/Sub message received';
    console.error(`error: ${msg}`);
    res.status(400).send(`Bad Request: ${msg}`);
  if (!req.body.message) {
    const msg = 'invalid Pub/Sub message format';
    console.error(`error: ${msg}`);
    res.status(400).send(`Bad Request: ${msg}`);

  const pubSubMessage = req.body.message;
  const name =
    ? Buffer.from(, 'base64').toString().trim()
    : 'World';

  console.log(`Hello ${name}!`);

module.exports = app;


@app.route('/', methods=['POST'])
def index():
    envelope = request.get_json()
    if not envelope:
        msg = 'no Pub/Sub message received'
        print(f'error: {msg}')
        return f'Bad Request: {msg}', 400

    if not isinstance(envelope, dict) or 'message' not in envelope:
        msg = 'invalid Pub/Sub message format'
        print(f'error: {msg}')
        return f'Bad Request: {msg}', 400

    pubsub_message = envelope['message']

    name = 'World'
    if isinstance(pubsub_message, dict) and 'data' in pubsub_message:
        name = base64.b64decode(pubsub_message['data']).decode('utf-8').strip()

    print(f'Hello {name}!')

    return ('', 204)


// PubSubMessage is the payload of a Pub/Sub event.
type PubSubMessage struct {
	Message struct {
		Data []byte `json:"data,omitempty"`
		ID   string `json:"id"`
	} `json:"message"`
	Subscription string `json:"subscription"`

// HelloPubSub receives and processes a Pub/Sub push message.
func HelloPubSub(w http.ResponseWriter, r *http.Request) {
	var m PubSubMessage
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Printf("ioutil.ReadAll: %v", err)
		http.Error(w, "Bad Request", http.StatusBadRequest)
	if err := json.Unmarshal(body, &m); err != nil {
		log.Printf("json.Unmarshal: %v", err)
		http.Error(w, "Bad Request", http.StatusBadRequest)

	name := string(m.Message.Data)
	if name == "" {
		name = "World"
	log.Printf("Hello %s!", name)


import java.util.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

// PubsubController consumes a Pub/Sub message.
public class PubSubController {
  @RequestMapping(value = "/", method = RequestMethod.POST)
  public ResponseEntity receiveMessage(@RequestBody Body body) {
    // Get PubSub message from request body.
    Body.Message message = body.getMessage();
    if (message == null) {
      String msg = "Bad Request: invalid Pub/Sub message format";
      return new ResponseEntity(msg, HttpStatus.BAD_REQUEST);

    String data = message.getData();
    String target =
        !StringUtils.isEmpty(data) ? new String(Base64.getDecoder().decode(data)) : "World";
    String msg = "Hello " + target + "!";

    return new ResponseEntity(msg, HttpStatus.OK);

You must code the service to return an accurate HTTP response code. Success codes, such as HTTP 200 or 204, acknowledge complete processing of the Pub/Sub message. Error codes, such as HTTP 400 or 500, indicate the message will be retried, as described in Receiving messages using Push.

Create a service account for the subscription

You need to create a service account to associate with your Pub/Sub subscription, and give it the permission to invoke your Cloud Run service. Pub/Sub messages pushed to your Cloud Run service will carry the identity of this service account.

You can use an existing service account to represent the Pub/Sub subscription identity, or you can create a new one.

To create a new service account and give it permission to invoke the Cloud Run service:


  1. Visit the Create service account key page in the Cloud Console.

    Create service account page

  2. From the Service account list, select New service account.

  3. In the Service account name field, enter the name you want to use for the service account.

  4. Click Create.

  5. Copy the service account email to use in the following steps.

  6. Click Continue if prompted to specify permissions.

  7. Visit the Cloud Run Services page in the Cloud Console.

    Go to the Services page

  8. Select your service in the displayed list.

  9. If necessary, click the Show Info Panel/Hide Info Panel toggle in the far right of the page to show information.

  10. Locate the Permissions tab, and in that tab, click Add Member.

  11. Paste your service account email into the New members field.

  12. From the Role dropdown menu, select Cloud Run > Cloud Run Invoker.

  13. Click Save.

Command line

  1. Create the service account:

    gcloud iam service-accounts create SERVICE-ACCOUNT_NAME \
       --display-name "DISPLAYED-SERVICE-ACCOUNT_NAME"


    • SERVICE-ACCOUNT_NAME with a lower case name unique within your Google Cloud project, for example my-invoker-service-account-name.
    • DISPLAYED-SERVICE-ACCOUNT-NAME with the name you want to display for this service account, for example, in the console, for example, My Invoker Service Account.
  2. For Cloud Run, give your service account permission to invoke your service:

    gcloud run services add-iam-policy-binding SERVICE \ \


    • SERVICE with the name of the service you want to be invoked by Pub/Sub.
    • SERVICE-ACCOUNT_NAME with the name of the service account.
    • PROJECT-ID with your Google Cloud project ID.

Validating service accounts (Cloud Run for Anthos on Google Cloud)

If you are using Cloud Run for Anthos on Google Cloud, you must verify the identity within the container by verifying the token in the Authorization: Bearer header. Refer to the IAP sample code for a code sample. Note that although the sample code shows using an IAP header rather than the Authorization header, the tokens are the same.

Creating a Pub/Sub topic

Requests to your service are triggered by messages published to a Pub/Sub topic, so you'll need to create a topic:


  1. Visit the Pub/Sub topics page in the Cloud Console.

    Pub/Sub topics page

  2. Click Create a topic.

  3. Enter a unique Name for your topic, for example, MyTopic.

Command line

gcloud pubsub topics create TOPIC-NAME

Replace TOPIC-NAME with a topic name unique within your Google Cloud project.

Create a push subscription and associate it with the service account

After you create the Pub/Sub topic, you must subscribe your service to receive messages sent to a topic, and you must associate the subscription with the service account you created for your service. You can use either the Cloud Console or the gcloud command line:


  1. Go to the Pub/Sub topics page.

    Pub/Sub topics page

  2. Click the topic you want to subscribe to.

  3. Click Create Subscription to display the subscription form:

    subscription form

    In the form,

    1. Specify the push delivery type.
    2. For Endpoints URL, specify your service's URL, which is displayed in the service detail page.
    3. In the Service Account dropdown, select the service account that you created with the required permissions.
    4. Set subscription expiration and acknowledgement deadline as desired.
    5. Click Create.
  4. The subscription is complete. Messages posted to the topic will now be pushed into your service.

Command line

  1. Allow Pub/Sub to create authentication tokens in your project:

    gcloud projects add-iam-policy-binding PROJECT-ID \ \


    • PROJECT-ID with your Google Cloud project ID.
    • PROJECT-NUMBER with your Google Cloud project number.

      Project ID and project number are listed in the Project info panel in the Cloud Console for your project.

  2. Create a Pub/Sub subscription with the service account that you created with the required permissions:

    gcloud beta pubsub subscriptions create SUBSCRIPTION-ID --topic TOPIC-NAME \
       --push-endpoint=SERVICE-URL/ \


    • TOPIC-NAME with the topic you previously created.
    • SERVICE-URL with the HTTPS URL that was provided when you deployed the service. You can find it by using the command gcloud run services describe, specifying the name of your service: look for the return line starting with domain.
    • PROJECT-ID with your Google Cloud project ID.

    The --push-auth-service-account flag activates the Pub/Sub push functionality for Authentication and authorization

  3. The subscription is complete. Messages posted to the topic will now be pushed into your service. You can push a test message to the topic using the command:

    gcloud pubsub topics publish TOPIC --message "hello"

    Replace TOPIC with the name of the topic you created.

What's next