I have an application where the client uses mutual SSL authentication through NGINX. So far, so good.
However, I want to move my project to Google App Engine and I need to use the same approach to valid the client, or at least, forward the client certificate to be validate in the application.
Is there some way to use mutual authentication on App Engine or other Google Cloud service?
Regards!
This might not be possible in GAE flexible environment because the SSL connections don't reach all the way to the actual application code. From Request limits:
SSL connections are terminated at the load balancer. Traffic from the load balancer is sent to the instance over an encrypted channel,
and then forwarded to the application server over HTTP. The
X-Forwarded-Proto header lets you understand if the origin request was
HTTP or HTTPs.
I didn't find such mention about the standard env GAE, so I'm unusure if the same applies there or not.
Related
I have a client that uses TLS authentication using X.509 certificates. The Client makes API calls to my GCP app engine, which acts as a REST server.
The app engine has Identity Aware Proxy enabled, but the client is unable to use that to authenticate via that. Therefore, I made a API gateway for the client to make HTTPS requests. But it is unable to make HTTPS requests without authenticating with X.509 certificates.
I am able to upload a cert.pem to the client. I generated the certificate in Google cloud shell using openssl. But I do not know where do I put this certificate in the GCP. Is it in App Engine->Settings->SSL certificates OR in the .yaml config file for the API gateway OR do I have to set up a load balancer?
API Gateway, App Engine, and HTTP load balancers do not support client authorization with X.509 certificates.
You must implement client X.509 authentication in your application or web server on a service you manage and deploy such as Compute Engine.
I am building a microservice architecture and I need help with internal/external communication.
I have microservices which are deployed on GCP App Engine Flex and have GCP API Gateway that sits in front of them. API Gateway handles external communication authentication using a JWT token sent in request header signed via service account private key.
On App Engine, we have configured Ingress (Internal + Load Balancer), so the App Engine's appspot URL are blocked externally. Each service has load balancer on which IAP is enabled and only API Gateway's service account has IAP-Secured Web App User role to pass request to LB.
My questions are :
Should GCP API Gateway be used for internal service to service communication ?
Since we have ingress (Internal + Load Balancer) enabled on App Engine and appspot URL are only accessible inside GCP project, can these URL be used for internal service to service communication ? Is this secure / recommended approach ?
Which of the above 2 suits well for the architecture to manage secure communication. Also, if possible, please suggest some alternatives.
Update : Adding flow diagram for both approaches
If you use ingress internal + LB for internal communication that means only the traffic coming from the VPC (of the current project) or the traffic coming from LB (of the current project) will be able to reach the service. Keep in ming that even if you set your traffic to internal, the IP is ALWAYS publicly accessible. There is simply an additional check perform on the traffic origin.
If you have another service on App Engine flex in your project, it should use either the LB (possible) or the VPC (route the traffic to the VPC even if it's a public URL -> That latest case is possible with Cloud Functions Cloud Run and App Engine standard (egress control feature, route all the traffic to the serverless VPC connector), but you can't with flex environment.
In addition, API Gateway can only reach public URL, and therefore you can only use the LB to reach your App Engine flex, and not the "internal" VPC traffic.
I have deployed an app in gcloud appengine. The main site is secured through a google managed certificate in app engine. However, after the authentication through auth0, the redirected url reviewresponse.beratics.com/dashboard is no more http secured although it has a certificate. That means I can change the url manually to https://reviewresponse.beratics.com/dashboard and it works. But it does not work automatically. What can I do, where is the problem? I have implemented pyopenssl and other measures such as talisman in python but the problem still persists. The backend is in flash, the app is on gcloud appengine flexible environment and the site is wordpress managed. The authentication to app works through auth0. All the callback Urls at Auth0 are with https. Thanks in advance!
I think this is what you are looking for, but App Engine has a secure flag in the app.yaml config which you can set to always which will redirect all http traffic to https. The details of this you can find here
Google Cloud app.yaml ref CTRL+F for 'secure'
As a possible workaround, GCE VM's allows custom firewall rules without any load balancer in front of them, in other words, you can use a GCE VM as a "proxy" setting a static IP blocking traffic over port 80 to then redirect to App Engine.
Also, I found this feature Request, as a kind recommendation you can start it in order that you receive further information about this.
Is my app secure with Google App Engine without my own SSL Certificate?
I ask because I've just gone through the process of using Letsencrypt to create an SSL cert and apply it to my App Engine project with a custom domain - myapp.com
Now, I also a development environment which is at myapp.appspot.com. While configuring the app.yaml files with secure: always, I accidentally deployed the dev app before creating the certificates and I noticed it was secured!
I thought this could be an appspot.com thing, so I removed the certificates from my live app and it is still showing as secured...
So the question is, does App Engine have some sort of built-in SSL and thus, do I need to bother with my own certs???
Yes, your app at appspot.com is secure. However, if you wish to use a custom domain then you must get an SSL certificate. Here you can find instructions on how to use a custom SSL certificate for a custom domain with appengine.
CONTEXT
Have created an API using Google Cloud Endpoints (Python) with which numerous low power devices will GET/POST data.
The only communication with the API will be from these custom devices (I own both ends of the communication).
RESEARCH
Looking at authentication, was hoping it would be as simple as using SSL/TLS client certs:
Each remote device will have a client cert signed by a single project CA anyway.
The Google cloud endpoints mandate SSL.
However, only oauth2 appears to be supported; I'm looking for a 'clean' way to implement 'hands off' authentication, ideally utilising the client SSL cert I already have on the client devices.
I have investigated creating 'service' oauth2 accounts, however as I want to protect against a device spoofing another device (one set of credentials for all is not acceptable), I would need to generate a service account for each client device, which would be bulky and horrible to maintain on the API-end.
It seems i'm looming towards needing to add a layer of authentication within my code for each API method, which somewhat defeats the point of utilising the services of Google's cloud endpoints.
QUESTION... Finally
Has anyone had experience in authenticating 'hands off' machine to machine devices at scale against google's cloud endpoint?
Does anyone know of a way of using a client certificate in the Oauth2 authentication process in a way which would be supported by GCE?
Is my only option going to be custom authentication within the API methods based on some crypto data in the POST/GET headers. (or just moving to hosting an API with Apache/NGINX and client-cert auth?)
Regards,
Matt
I wrote you an essay:
Consider that Cloud Endpoints basically exists in the application layer of the OSI model, since it communicates via HTTPS requests (it sends HTTP requests within a TLS session). Whether or not Endpoints uses HTTP or HTTPS is not a developer-configurable option - it must be HTTPS.
It uses HTTPS in that the API server has a TLS cert which is used to authenticate the API server. Inside the secure connection, the RPC params and responses are also secured from eavesdropping. This is the extent to which Endpoints "interacts" with TLS - it uses it to establish the session and send HTTP requests inside this session.
So, already I can tell you that you will not be able to have your TLS client certs (not an often-used feature) used to authenticate API clients automatically by endpoints, in the connection setup phase. TLS client certs simply aren't looked at or requested by the Endpoints API server.
Now, while authentication of the API server itself is guaranteed through the API server's TLS cert, authentication of API clients is done via Client IDs or the Users API, which sits in your code and abstracts over the different auth options App Engine offers at present:
OAuth (2.0)
OpenID
So, in order to auth your client devices in one of these two manners and still take advantage of Cloud Endpoints, you will need to find a way for each device to perform an OAuth flow or OpenID flow, your system having provisioned an identity for the respective auth method at the time of that device's initial deployment.
Google (Apps) Accounts option
This will involve creating a Google account (Google's unified SSO) or a Google Apps account managed by a custom domain for each device, and provisioning these accounts' credentials to each respective device. You can read more about custom domain authentication and App Engine auth configuration in general here.
OpenID option (general doc on OpenID with GAE)
This will involve setting up your own OpenID provider on a GCE instance using an OpenID connect library like pyoidc, so that you can provision accounts yourself, or it could involve registering accounts with a known OpenID provider for each device. The first solution is more robust but more time-consuming (OpenID providers can go down temporarily, or deactivate forever, and then your IOT network is out of luck).
Third option using Client IDs
You can of course generate an "installed application" client ID/secret and distribute these to each device in your network. They can use this to authenticate themselves as network devices (as opposed to an attacker's laptop), and then you trust devices to accurately report their own id as a param with each API call. Depending on how hackable your devices are and how widely you intend to distribute them, this scheme doesn't necessarily prevent devices from spoofing each other's id's, although depending on the id generation scheme, you can make it very difficult (each id being a long sufficiently long hash).
If you go this route and you're really concerned about this, you can provision a client ID for each device, but who knows if you'll hit some kind of undocumented limit on number of client IDs per app, and also this will require you to either do it by hand or write a script that logs into the dev console on a headless browser and does what you need.
Fourth crazy option that actually uses the TLS client certs
If you're really set on using both TLS client certs for auth and Cloud Endpoints for your API, you could try to send the client cert in the request, since TLS is encrypting the request data (unless your attacker has found a way to efficiently solve the inverse discrete logarithm problem, in which case they'll probably be too busy attacking more important targets (no offense) and changing the infosec game forever), and then reading and auth'ing the cert in your endpoints method somehow (third party libs uploaded with your app are probably necessary for this).
Fourth realistic option if you have your heart set on TLS client certs
Switch from App Engine to Compute Engine, where you basically have a VM managed and hosted in the same data-centers. On this box, you can implement any kind of connection protocol on any port you like, so you could have incoming API requests (not Endpoints, notice) TLS-authenticated based on teh connecting device's client certs.
Good luck!