13
votes

I'm using Google Cloud Run for a simple POC web app. My hope was to lean on GCP IAM to handle authentication for the time being, similar to how Identity-Aware Proxy (IAP) can be used in conjunction with App Engine or GKE.

When I gave the Cloud Run Invoker role to a user, I expected authentication to work similar to how IAP does (login redirect auth flow), but I get a 403 error instead. I can curl it setting the Authorization header though.

Is it required to implement authentication in the app for user-facing web applications? I was hoping to do a quick prototype by relying on IAM. If it is required, what would be the recommended way to implement OAuth2 authentication for a simple prototype? Firebase Authentication?

2
You will need to authorize your own Google OAuth tokens and then add to the HTTP headers.John Hanley
The current design of authorization for Cloud Run does not lend itself for websites. Think service to service authorization (APIs).John Hanley
Indeed, this is what I'm discovering. I guess my question really is: is Cloud Run actually intended for web applications at all or just "backend" services? It would seem more the latter. I would have expected similar behavior to IAP, especially since the role management has a very similar look and feel.Tyler Treat
Cloud Run works well for websites. Web Applications need clarifying as Cloud Run has HTTP run time limits (timeouts). For normal HTTP Request / Response designs I am impressed. I think that the authorization features might have been rushed to get into beta. I have a feeling that Google will put more work into this area before production status arrives. Providing feedback will probably help them decide on what's critical.John Hanley

2 Answers

9
votes

Run PM here,

Yes, right now you're required to host your own OAuth client, e.g.:

<html>
  <head>
    <title>Google Sign-in + Run</title>
    <script src="https://apis.google.com/js/platform.js"></script>
    <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
    <meta name="google-signin-client_id" content="{OAUTH_CLIENT_ID}">
  </head>

  <body>
      <div class="g-signin2" data-onsuccess="onSignIn"></div></br>
    <div>
      <div id="returned-text"></div></br>
      <button id="test">Test</button>
    </div>
    <script>
    var id_token;

    function onSignIn(googleUser) {
      id_token = googleUser.getAuthResponse().id_token;
    }

    $(document).ready(function() {
      $('#test').on('click', function () {
        var serviceURL = 'https://...';

        var xhr = new XMLHttpRequest();
        xhr.open('GET', functionURL);
        xhr.setRequestHeader('Authorization', 'bearer ' + id_token);
        xhr.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
               $('#returned-text').text(xhr.responseText);
            }
        };
        xhr.send();
      });
    });
    </script>
  </body>
</html>

Note that CORS will be wonky here, and we recommend hosting on the same origin to get rid of this (e.g. use the Firebase Hosting integration).

In the future, it's likely we'll offer IAP (which hosts an OAuth client for you).

1
votes

Inspired by @mike's approach I created a Cloud Run hosted version of an Identity Aware Proxy in a Terraform config.

https://futurice.com/blog/identity-aware-proxy-for-google-cloud-run