How to restrict access to GAE Flexible site only for GSuite account? - google-app-engine

How to restrict access to GAE Flexible site only for all account from my domain in GSuite and eventually other Google accounts that I provide explicitely. AFAIR there where something simillar in Standard GAE version in app.yaml handlers section.
So my scenario:
prodution versions restricted until go-live
dev and stage version restricted permanently
I would like to do this on the IAM level, to reject traffic to the site. But I didn't found anything in docs.

Ok, after rethink the problem and dig deeper in a documentation I found a page about dev environment - https://cloud.google.com/appengine/docs/standard/python/creating-separate-dev-environments.
So my current solution is not to have separate versions like dev, stage and prod and work with them within one project, but to create separate projects for each of environment.
It will also simplify management of DBs - previous I thought about different database in one DB server for particular environment. Now I will have a separate DB instance for it.
Anyway I still have a problem with securing access.
I did it in the same way like in Restrict App Engine access to G Suite accounts on custom domain:
changed Google Authentication to my Google Suite domain
added Custom Domain in my app
added my page domain to my GSuite as a second domain
And I still can connect to my page without auth - even in "Incognito mode" and on others computers and mobiles.
EDIT:
As a workaround I used Django-lockdown module. For the timebeing is more than enough - I have a password, I have a session, I can set it in Middleware or as a decorator for urls.
EDIT 2:
I noticed today a new feature in GAE Flexible - Identity-Aware Proxy.
This is the feature, that I was searching. You can restrict accces by:
Google Account email: user#gmail.com
Google Group: admins#googlegroups.com
Service account: server#example.gserviceaccount.com
Google Apps domain: example.com

Related

Setting target url with gcloud

I have been using the Google App Engine Launcher's "Deploy" button. I realize that the Launcher is going away at the end of July 2020, so I'm trying to learn to use gcloud. My web site has a custom url, www.xxx.org, but "gcloud app deploy" uploads to xxx.appspot.com instead of to www.xxx.org, presumably because "target url" is set to xxx.appspot.com. Can someone please tell me what gcloud command I need to use to change "target url" to www.xxx.org, or some other scheme that would work? I've wandered through lots of gcloud and GAE documentation and web searches without being able to figure out what I need to do.
There is a very good and complete guide about mapping a custom domain to your application in the official documentation. As #DanCornilescu said,it needs to be configured, but it is not necessary to be done before deployment.
Basically, you need to follow the steps from the guide:
1) Verify that you are the owner of your domain through Webmaster
Central
2)Ensure that your domain has been verified, otherwise you will not be able to proceed with the following steps. Note that only verified domains will be displayed.
3)If you need to delegate the ownership of your domain to other users or service accounts, you can add permission through the Webmaster Central page
4)After you verify ownership of your domain, you can map that domain to your App Engine app
5)Add the resource records that you receive to the DNS configuration of your domain registrar
6)Test for success by browsing to your app via its new domain URL, for example www.example.com
In case you need to do more complex mappings for different urls and subdomains you can always write down the routing rules in the dispatch.yaml file and they will be mapped successfully.
Also, to add a bit more of information about the dipatch.yaml file, it will handle the routing in the App as opposed with the app.yaml which will take care of the App's settings. Both .yamls can exist in the same application and can be deployed at the same time by using the following gcloud command:
gcloud app deploy app.yaml dispatch.yaml
The deployment is always done to .appspot.com, the custom domain is automatically updated if it is already configured. If it is not then it needs to be configured (it can be done after the deployment as well).

Google App Engine blocking access to my backend services

In Google App Engine, I have 3 services, 1 for front end, 2 for back end.
Is there a way to block http calls to my backend services for accounts not from my company's domain (and the service account of the front end), but allow everyone http access to my front end service?
I know there is the firewall option, but this is restricted to IP addresses, I would prefer user based
If it matters all services are python3
There's currently no option to filter traffic to specific App Engine services within a single application/project:
App Engine Firewall filters by source IP ranges but can only be set for the whole app, not per service.
Identity-Aware Proxy can filter access by user account as you'd prefer but also applies to the whole app. Also, it only supports user account and can't be used with service accounts.
One option you may have would be to split your app in 2 different projects. Keep the front-end in one project open to the world and restrict access to the backend services in your other project via firewall rules.
I have seen the following being used in task queues in GAE. Maybe it would help.
If u were using python 2, in standard environment, i think u could have used login handler element in app.yaml file.
You could have added following lines to your app.yaml file:
handlers:
- url: /.*
script: worker.app
login: admin
This prevents other users from accessing this service.
But the same login handler is not available for python3, according to Google Docs.
Just found following in Google Docs:
If a task performs sensitive operations (such as modifying data), you might want to secure the handler URL to prevent a malicious external user from calling it directly. You can prevent users from accessing task URLs by restricting access to App Engine administrators. Task requests themselves are issued by App Engine and can always target a restricted URL.
You can restrict a URL by adding the login: admin element to the handler configuration in your app.yaml file.
You can also call your backend services through cloud tasks or task queues (both are almost the same i guess), in case this only work for cloud tasks.
Find the code usage here:
https://github.com/GoogleCloudPlatform/python-docs-samples/tree/6f5f3bcb81779679a24e0964a6c57c0c7deabfac/appengine/standard/taskqueue/counter
Find details about handler here.
https://cloud.google.com/appengine/docs/standard/python/config/appref#handlers_element
Find details about Cloud task and queue here:
https://cloud.google.com/appengine/docs/standard/python/taskqueue/push/creating-handlers

Changing app engine service account roles not effecting access

My goal is to run a google app engine application with the minimal amount of access to resources it needs. In my case the application will access the datastorage in the project (this is the golang example tutorial using the source code git checkout origin/part4-usingdatastore from https://github.com/GoogleCloudPlatform/appengine-guestbook-go.git)
I did the following
Create a new project, foobarproject3
Created a new app in the project (using golang)
In the project IAM/IAM noticed the
foobarproject3#appspot.gserviceaccount.com, assumed this is the service account, so changed it's role to just BigQuery User. Notice that no Datastorage roles are configured (The UI forces me to provide access to something so I chose BQ)
Followed the tutorial instructions for the using datastore golang app (guestbook application)and deployed the app.
Opened the link to my app: https://foobarproject3.appspot.com/ It failed (this is great, this is what I expected, since the service account does not give the app permissions to read/write datastorage)
Refreshed https://foobarproject3.appspot.com/ and it started to work
There is something basic that I'm not understanding about service account from app engine. Isn't the app engine using these service account to access project resources? Why is the app getting access to datastorage when the service account does not have a policy that would allow access to datastorage?
"My goal is to run a google app engine application with the minimal amount of access to resources it needs."
This is dicey to unpack without more context. What is it that you're trying to achieve that goes beyond App Engine's default behavior?
My experience is that if one starts changing roles without understanding the basics, things go sideways (or South, or West, or Pear-shaped, depending on where you are). So I suspect you shot yourself in the foot in your third bullet.
When you access your app from the browser you are using your own user credentials, not the app's service account. And your user credentials might be exactly the app owner/admin ones, if you created the app using those credentials. See, for example, app.yaml handler login: admin option not effective on standard env python GAE app?
Make sure you log out from the app, or try accessing the app from an incognito browser window or by using a dumb(er) utility to prevent accidental/undesired credential leaking.
The app's service account is for your app to identify itself when it's interacting with other services/apps. From Understanding Service Accounts:
A service account is a special type of Google account that belongs to
your application or a virtual machine (VM), instead of to an
individual end user. Your application assumes the identity of the
service account to call Google APIs, so that the users aren't
directly involved. A service account can have zero or more pairs of
service account keys, which are used to authenticate to Google.

hide app from public in Google App Engine

I've read some info about authentication, but I would have thought that I could turn off my app's visibility and/or access to the public. This would be useful for alpha testing so surely a setting like this exists? Or do I need to build such things into the app itself?
Without some sort of authentication mechanism your app can't really distinguish between a request coming from you and one coming from someone else.
It might be a good idea to spend a bit of time to analyze your app's authentication requirements and maybe get it done now, while still in alpha.
Depending on the solution it may be fairly simple to integrate.
Google offers multiple authentication options, see What is the difference between Google identity toolkit, Google OAauth and Google+ sign in
I personally opted for the GIT kit for simplicity, flexibility and convenience.
It's possible secure your App's urls so only an authorised user or administrator can access them.
This can be done through the app.yaml file (Python, PHP and Go applications) or the web.xml deployment descriptor (Java applications).
Option A:
Just allow only admin access, in yourapp.yaml
- url: /*
login: admin
script: yourappname.app
Option B:
If you have an static IP (or with a few changes a week), you can detect the IP of the request and let run only from your IP:
class yourHandler(webapp2.RequestHandler):
def get(self):
userIP=self.request.remote_addr
if userIP=="220.123.211.120" # Change this with your static IP
...your code for authorized users.
Option C:
Check request domain (to ensure is called from your own authorized domains), and put some security client side.
class yourHandler(webapp2.RequestHandler):
def get(self):
origin=self.request.headers['Origin']
if origin=="www.yourdomain.com" # Change this with your domain/subdomain
...your code for authorized users.
# I recommend to put also the CORS headers for your own domain
self.response.headers['Access-Control-Allow-Origin'] = "www.yourdomain.com"
Personally, I have a mix of the three options plus a custom authentication to access private content.
By default, every service is born public. Change that, individually, by changing the --ingress setting for the service you want.
gcloud beta app services update <service-name> --ingress <value>
all (default): public to internet.
internal-only: only accessible for resources in the same Cloud Project.
internal-and-cloud-load-balancing: only accessible for resources in the same Cloud Project. And those requests came from configured Cloud Load Balancing.
1 Gateway + a bunch Microservices architecture example:
gcloud beta app services update ms-payment --ingress internal-only
gcloud beta app services update my-backend-gateway --ingress all << default!! Just for example purpose.
In this way, ms-payment is accessible only by resources within the same Cloud Project, even if they are in different VPCs.
Refer the documentation: https://cloud.google.com/appengine/docs/standard/java11/application-security#ingress_controls
I've found recently that you could also use IAP (Identity-Aware Proxy) IA-what? I found a tutorial that implements it on App Engine.
Tutorial for App Engine.
So I didn't want to rely on my own authentication implementation because I'm not an expert, and security it's something very hard to learn in a rush. In a nutshell
Deploy an IAP step 1
Add your app engine (or the whole scope) to your IAP
add your authorized emails on the left panel step 3. For access use:
IAP-Secured Web App User: Grants access to the app and other HTTPS
resources that use IAP.
My Personal opinion here: try to implement as many safety measures as possible (don't rely on one system only), usually they could fail.

SSL Error using custom domain with Google App Engine

I followed the steps detailed here to use a custom domain with google app engine.
I'm the admin of the Google Apps account
I'm the owner of the Google App Engine account
I've added the domain to my Google Apps account through my App Engine account
I see my App Engine app in my Google Apps account
I set the CNAME "test" to point to ghs.googlehosted.com
I added the web address under my Google Apps account and it says "Your users can access my-app-id at: test.mydomain.com
Now when I go to http://test.mydomain.com, it redirects to https://test.mydomain.com and I get an SSL connection error (Unable to make a secure connection to the server.)
I called Google Apps customer support because I have a paid business account, but the customer service guy said that this falls under App Engine support and he was not trained in this issue.
Help!
If you've done everything correctly, you should be able to access your site at http://test.mydomain.com. It sounds from the error you're getting that you're attempting to access it at https://test.mydomain.com (https as opposed to http).
If you want to access your app over SSL at your custom domain, you have more setup to do, as documented here: SSL for a Custom Domain. The steps necessary are many and subject to change; that link is the official source of current information on the matter.
Update: From your updated information, it sounds like you may have secure: always set in your app.yaml, or the Java-configuration equivalent of this setting. It would be helpful if you posted your configuration file.
Also note that it takes several minutes for Google to add a certificate on a domain you recently imported (it may require time for DNS configuration to spread). I personally didn't need to add any secure: configuration, it just worked after some time.

Resources