Can I use google service accounts to authenticate INCOMING requests? - google-app-engine

We currently have an App Engine application plus some Google Compute Engine backends. Unfortunately App Engine is not considered "in-network" so in order for App Engine to make requests to backend servers, the relevant ports must be made publicly available in the firewall which is obviously a security risk. It would be very convenient if our App Engine app could automatically "sign" all request to our backends by using a service account client to issue the requests. Is this possible?
And likewise, I'd love to also do this in the other direction, where requests from our GCE servers could be authenticated by App Engine as long as the requests are issued from a GCE service account. I naively tried the latter by issuing a request from GCE to a test handler on app engine that checks the current user (via the Users service) but unsurprisingly the user was null (since "users" and "service accounts" aren't exactly the same I didn't expect this to work - but hey worth a shot).
There's a fair amount of info on the web for issuing service-account-authenticated requests (e.g. to google APIs) but I can't find anything on authenticating incoming requests. Does such a thing exist? (ideally in Go)

There is a new feature coming out soon called Managed VMs. You can click on the following link for more details and signup for updates https://developers.google.com/cloud/managed-vms.

Related

Forwarding OAuth 2 credentials from an authenticated request (in GCP specifically)

I have an AppEngine application that is behind an IAP (identity-aware proxy), so it receives requests that are authenticated and include a JWT token. From the AppEngine application I want to make a request to the Google Sheets API. That also requires an authenticated connection, but given that I want that connection to be made under the same user that accessed the application via the IAP, does anyone know how to create a request from inside the AppEngine application that will forward the token to Google Sheets? Cannot find any information on the subject... I am using Java, so any Java pointers would be appreciated, but general/other language help is good too...
I will describe the 2 approach proposed in the comment
The first one, to reuse the IAP proxy token to access Google Sheet is impossible, and dangerous.
Impossible because you receive an identity token from IAP (at least the requester/browser send an identity token to IAP) and you need an access token to request Sheet APIs.
Dangerous because, if you are able to reuse the IAP token to request the Google Sheet, that means the user is authorized to access to the Google Sheet. And I'm sure that you build an app to prevent any direct access/modification to the Google Sheet.
The second one, is to use a technical account (typically a service account) and generate an access token to access the Sheet API.
This second approach is the best one (don't forget to correctly log the user request and the subsequent sheet API calls in your AppEngine app to have the end to end traceability). BUT, and it's for that you ask this question, it's impossible with the App Engine default service account.
In fact, to access to the Sheet API, you need to scope your access token with the Sheet API. Sadly, you can't do this with App Engine. You can do this with Cloud Run, Cloud Functions, Compute Engine (without the default service account, else you need an extra config to achieve this with the Compute Engine default service account). But not with App Engine.
So, you have 2 solutions:
Either you use another hosting platform (Cloud Run for example), but you loose the IAP capacity (for now)
You continue to use App Engine but you need to request an access token to another service account (it's not required to have a service account key file). You can use the Service Account Credential API for this. I wrote an article on this API
Note: later in 2021, App Engine should be able to accept custom service account, and thus the issue should be solved

Sending authenticated HTTP requests from ComputeEngine to AppEngine using the default service account

For a project that I'm currently developing, I need to expose a servlet (hosted on Google App Engine) to a Java executable which is hosted on Google Compute Engine (in the same project). Such servlet performs some maintenance tasks, so it should never be triggered by non-authorized users. So, the goal is to authorize the requests coming from the Google Compute Engine instance that is running the JAR executable.
In the past I've solved the same issue by having the servlet exposed on HTTPS and rely on a "shared secret", known both to AppEngine application and to the JAR running on the Compute Engine instance. In that way, the instance calls the specific servlet (which is public), then the servlet verifies if the secret is correct, and if so, the request is allowed.
I don't like this approach. For sure we can do something better using challenge-response authentication or by using some other authentication procedure (probably via asymmetric crypto signing). However, this is not what I want to do.
My preferred way of acheiving the same result would be by using the Compute Engine Default Service Account. I am pretty sure there is a way of creating a HTTP POST request on the compute engine and authenticate that via the default service account key. Then, on the servlet, I would rely on the UserService to check whether the request is coming from the ComputeEngine default service account, and if so, I would accept that.
However, I have not seen any documentation or code example that explains how to do that. I suspect there might be possible to perform an authenticated HTTPRequest using the default Compute Engine Service Sccount (maybe adding the Bearer JWT token as Authorization header?).
Has anyone tried something like that?
You have several options; OAuth is likely your best bet.

Reading a users gmail in Google app engine app

I am the admin of a Google domain and I need to he able to read users emails in my php app. How is this possible? I have tried to use IMAP but it won't even connect. Is there something special that apps have to do?
Here is a list of all the ways to read a user's Gmail mailbox, outside of App Engine :
IMAP, as you said. Provided it is enabled on your domain. Most of our customers disable it for security reasons (no audit trace of the connections).
Apps Script, but it requires the user's consent, even if you're an admin
The Email Audit API, but an Email extraction takes approximately 2 weeks (no kidding)
If IMAP is enabled on your domain, then it's the best choice. However, by default GAE does not allow outgoing connections apart from HTTP requests. The workaround for this limitation is the Sockets API, currently in preview. You can check it out here.
Note that you will also need to use an OAuth2 service account (domain-wide delegation) and IMAP-XOAuth2 to authenticate with the IMAP protocol.

How is the user authentication with Google accounts working inside the GAE technically

Applications that run inside the Google App Engine can use Google Accounts for user authentication. I already used this feature and it works great. I just want to know how this is working. Is there a HTTP cookie created? How can an application inside the GAE see that a user is logged in?
The AppEngine SDK takes care of the details for you, but essentially it generates the equivalent of an OAuth request to the Google Account service. All interactions with the login process go through the Google Account service (and thus the cookies it uses for session tracking are not available to the individual app).

Can you use Google App Engine to send emails from an application hosted elsewhere?

I need to send emails from my web application (on account creation, password reset, etc.). This application will most likely be hosted on a standard hosting site (or possibly on Amazon EC2), not on Google App Engine.
However, I like the ease of use for sending email through App Engine. Is there a way to host your application elsewhere but use App Engine to send emails programatically? I suppose I could send a web request from my application to a custom application on App Engine, parse the request, and then send the email from App Engine.
However, I would like to avoid having to create an application on App Engine even if it is very simple as it would be another item to maintain. Is there a simpler way to just use App Engine as the email gateway, similar to using Google Apps for my Domain?
I don't need to receive email by the application. Also, I would like all emails to come from the same domain (like mail#example.com) regardless of if it were sent from the hosted application or App Engine.
You can do this using remote_api. Simply upload a Python app with nothing but the remote api handler included; you can then use the Python remote api library to send emails via App Engine.
Note that emails sent by the App Engine Mail API have to be from an administrator of the app (or the logged in user, but this doesn't apply over remote api). Thus, you'll want to add whatever from account you want as an administrator to the app.
Edit: As mentioned, I am totally wrong! Above post is correct.
First, I am very positive if you want to use App Engine's features you need to actually build an app on it. You can't use their API on external applications. You are right though that you could simply send a request to your app engine app if you wanted it to send email. I don't see how it would be too hard to maintain if that's all it is doing.
Second, if you are planning to send emails via GMail's service, they don't allow you to mask the from address so you will always see it from whatever gmail address you're sending it from.
Why not just send emails from your application but use whatever email service you use now? In most languages and frameworks, SENDING email and not managing it is a breeze.

Resources