1

I have an application deployed on cloud run, and I created a cloud scheduler job that calls an endpoint on this application.

I created a service account and use it for the cloud task token. Below is a screenshot of the cloud scheduler task configuration (I ensured multiple time the right service account is selected).

enter image description here

I have a middleware on my application to prevent unauthorized access to the endpoint (simplified version):

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "google.golang.org/api/oauth2/v2"
    "net/http"
    "strings"
)

func ForceCloudScheduler(c *gin.Context) {
    if c.Request.UserAgent() != "Google-Cloud-Scheduler" {
        c.AbortWithStatus(http.StatusForbidden)
        return
    }

    // https://stackoverflow.com/questions/53181297/verify-http-request-from-google-cloud-scheduler
    token := c.GetHeader("Authorization")
    if token == "" {
        c.AbortWithStatus(http.StatusForbidden)
        return
    }
    idToken := strings.Split(token, "Bearer ")[0]

    authenticator, err := oauth2.NewService(c)
    if err != nil {
        _ = c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to acquire authenticator: %w", err))
        return
    }
    info, err := authenticator.Tokeninfo().IdToken(idToken).Do()
    if err != nil {
        _ = c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to retrieve token information: %w", err))
        return
    }

    // This is the line where the job fails.
    if info.Email != "agora-job-scheduler-account@agoradesecrivains.iam.gserviceaccount.com" {
        c.AbortWithStatus(http.StatusForbidden)
        return
    }

    c.Next()
}

When I run the job, the request fails with a 403. I have added some logs to check the content of the token sent by cloud scheduler. Here is the logs explorer output:

{
    "audience": "107655128939031897672"
    "email": "970356934135-compute@developer.gserviceaccount.com"
    "expires_in": 1644
    "issued_to": "107655128939031897672"
    "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email"
    "user_id": "107655128939031897672"
    "verified_email": true
}

For some reason (maybe a bug?), the email in the token payload does not match the one I set in cloud scheduler. Is this expected and can I fix that ?

KawaLo
  • 1,783
  • 3
  • 16
  • 34

1 Answers1

1

The documentation says that,

Do not remove the default Cloud Scheduler service account from your project, or its Cloud Scheduler Service Agent (roles/cloudscheduler.serviceAgent) role. Doing so results in 403 responses to endpoints requiring authentication, even if your job's service account has the appropriate role.

You can refer to this Troubleshoot Cloud Run issues document where it states different reasons for causing the 403 error and respective resolution steps.

For more information, you can refer to these Stack Overflow Link1 and Link2 which may help you.

  • Thanks for the useful links, however it doesn't solve my issue for now. The 403 does not come from GCP, it comes from my application, and Cloud Scheduler actually manages to call Cloud Run without any issue. What I am facing is that Cloud Scheduler sends a token with the wrong credentials, it doesn't use the service account I selected in the task configuration. The token is valid, it manages to verify and decode the payload. My endpoint is called. But when my app checks the payload email, it does not encounter the expected value. – KawaLo Nov 30 '22 at 10:08
  • Can you go through with this [Stackoveflow Link](https://stackoverflow.com/questions/58480834/cant-create-job-on-gcp-cloud-scheduler) – Sandeep Vokkareni Nov 30 '22 at 14:43