Is it safe to hardcode an API secret on Google App Engine? - google-app-engine

I'm going to be making queries to Balanced's credit card processing servers using tokens stored in the App Engine datastore. This requires using an API secret string for the queries. If I hardcode the API secret into my app code and disable source downloading by admins, is there any way for a potentially malicious admin (who doesn't know the secret) to find out what the secret is (assuming it's in the code, not the datastore)?
I'm using Google App Engine for Java. The API secret is just a string.
Thanks

If no "potentially malicious" people have access to your source code, it is perfectly safe to include an API secret in your server-side code.
All samples for App Engine to API code include "hardcoded" API/client secrets. For example: here.

Related

How to use Google Cloud KMS key as SigningCredential in IdentityServer4?

I have an IdentityServer4 app running on App Engine. As I prepare for production, I have a lot of confusion using .AddSigningCredential() in this scenario. In app engine, I don't have a file system to cert store in a traditional sense, and it seems like I can only pass in a path to a cert/key or the contents itself.
As I'm hosting on Google Cloud, I would like to use KMS. The API for KMS gives me the ability to sign something, but Identity Server doesn't give me a way to use that, and I don't see a way for KMS to give Identity server what it wants.
The only workaround I came up with is to generate a key pair, save it as a secret, and pass that in to .AddSigningCredential(). The downside is that now I have to manage this key/secret manually. There must be another way.

Estimating cost of Google App Engine API script using “x-appengine-estimated-cpm-us-dollars” header

I created an API using Python + FastAPI and deployed it to Google App Engine and I would like to measure the cost for each request made.
I saw there is a header "x-appengine-estimated-cpm-us-dollars" that show up when logged in with the owner account on GAE, but I didn't see it when accessed the API using the browser "https://example.uc.r.appspot.com/api"
Any idea how to can I see this header or a way to get an estimated cost for each request made?
Note: the deployed script is an API, not a website with auth like the one mentioned here (Usage of X-AppEngine-Estimated-CPM-US-Dollars in AppEngine)
According to the documentation:
If you access dynamic pages on your site while signed in using an administrator account, App Engine includes per-request statistics in the response headers
And then shows the description for this particular header, therefore, this is not something that is available for APIs hosted in AppEngine.
You could alternatively use the Cloud Billing API to gather some information, although not exactly the same.

How to secure third party API keys in firebase hosting?

I am using different third party API keys in my reactjs-firestore project. But I can't find a way to secure them in firebase hosting. How can I hide these API keys in firebase hosting?
For example, in Netlify hosting services they provide environment variables feature which can be used to secure the API keys.
that is I can just store the API keys in the variables in netlify and it will be retrieved from there which will be secured.
But in firebase how do I do this?
I can't seem to find a similar setting wherein I can store the keys as environment variables in the hosting services.
if there is no such feature is there another way to secure these API keys?
and for the firebase API keys,
I have already read some answers and understood that firebase API keys will not be hidden.
is there at least some way to secure these firebase API keys to just one secured URL at least? (I know that writing security rules is the best approach but am trying to find other options as well).
I can't seem to find a way to secure firebase project API key usage to one secured URL.
I have tried to find ways to secure the API key but I haven't been successful.
below is how I retrieve data in reactjs code
axios.post(`https://data.retrieval.com/1/data?key=API_KEY`, data)
I am trying to hide the API_KEY in the production code
I want to secure third party API keys in my hosted website.
and also restrict my firebase project API key to just one secure URL.
am not able to do this now.
any suggestions or solutions?
Thank you for trying to help.
and thank you for your time
If you're using the API key in client-side code, there is always the chance that a malicious user can find the key and abuse it. The only way to protect against this is to not use the API key in client-side code, or to have a backend system that can protect access based on something else (such as Firebase's server-side security rules).
Since your backend system likely doesn't have such a security model, you'll typically have to wrap their API in your own middleware that you host in a trusted environment such a server you control, or Cloud Functions. That's then where you ensure all access to the API is authorized, for example by setting up your own security system.
Not sure if this help, but my Firebase Cloud Function use this.
Create your secret by
firebase functions:config:set secret.API_KEY="THE API KEY"
Access your secret by using functions.config().secret.API_KEY
Note: This should only use for server use case, not in the client code. For server I meant Firebase Cloud Function or your backend.
The safe way I've found to store your third-party keys is using the Google Secrets Manager. It is now baked into the Firebase Functions SDK and works very well. You can find the information here, under the section titled "Store and access sensitive configuration information".
Two things worth mentioning:
There is a small bug in the syntax example, they forgot to add the https before onCall.
You'll need to give the service account which runs the cloud function when deployed access to the secrets. Here are the official docs on how to do that. If you are deploying through Firebase, you'll want to look for the service account whose address is [project-name]#appspot.gserviceaccount.com. If you have any doubts about which service account is running the Cloud Function, look under the Details tab in the Cloud Functions section of Google Cloud Platform and it will show you that information. Also, under the Variables tab, you can see what secrets your Cloud Function has access to.
This process makes it really easy to manage third-party keys as you can manage them at your project level and not have to worry about them being stored else where or needing to manage .env files. It also works with the Firebase Emulators and uses the credentials of the user running the emulators for access.

AppEngine Multi backends keeping autoscaling

I have an AppEngine webapp with a JavaScript tracker. I want it to make HTTP calls to a collector (which is a REST API that saves data into BigQuery) without making an entire app-to-app authentication process with OAuth/JWT or whatever.
According to this thread it's not possible for AppEngine to use a REST API located on a compute engine instance with an internal IP.
In addition, it seems that it's not possible to use GAE multibackends feature since it loses autoscaling and I really need this feature.
What is the proper Google Cloud way to achieve this ?
I presume that the collector is running on compute engine and the problem is how to verify that requests to the collector are genuine requests from the AppEngine service since the only way for the AppEngine app to reach the collector is via a public IP.
AppEngine has an Identity API for an AppEngine to assert to a third party service that a request is genuine. A more detailed (and less contrived) example of how to use this is discussed here. The code link no longer works but the code is available here.
This specific sequence from the last article seems to be more or less what you need:
Client App generates a signed blob by calling app_identity.signForApp(string_blob)
Client App exposes its public certificates on a public endpoint, for example clientapp.com/certs. In the demos below we use a trivial Json format to expose certificates, something like: {"cert1":"x509 cert pem", "cert2":"x509 cert pem 2"...}.
Client App sends a request to API App along with the signed blob and the URL that contains Client App's public certificates.
API App fetches Client App's public certificates from that URL
API App verifies the signature of the signed blob. The API App might perform other business logic like checking if the Client App (as identified by the URL of its public certificates) is on an access control list.
Both apps should agree on the same 'signed blob' format. In our demo we use JWT as the signed token format. The detailed spec can be found at http://self-issued.info/

Google Cloud Storage Authentication

I build Android app link to Google Cloud Storage. I want to allow access to GCS to my android app ONLY.
Google offers three solutions to securely connect to GCS:
Oauth 2.0 (So with google account)
Cookie-base Account (With google account too)
Service Account Authentication (With private Key, but locally installed on Android App: Very Bad if someone decompile my .apk)
Source: https://developers.google.com/storage/docs/authentication?hl=FR
Is there any other solution to connect securely over GCS ? I would like to connect on GCS to this way (Restrict to Android client ID: SHA1 to your .apk) : https://developers.google.com/appengine/docs/java/endpoints/auth
It is possible with GCS ? Should I use Blobstore to do that ?
Thanks in advance
This is something of a fundamental problem with computing. You can never completely trust that an application running on hardware that is under the total control of an unknown third party has not been somehow tampered with. There are many, many techniques to make tampering much more difficult, but remote systems will never be completely secure. There are several ways to verify that a user has a particular Google account, but you can't easily trust with certainty that a certain app is exactly your app.
That said, there are plenty of ways to design a secure application without trusting the client. What does your app need to be authorized to do? Upload objects? Download secure objects? Is there something bad that a user masquerading as your application could do?
I think you can use 1) to authenticate the information. The app will forward the authentication request to your server (with your own app login token), and when the user is validated by your own services, then the app will receive the oauth token to send to gcloud and receive the desired file.

Resources