I have a google app engine application which needs to be given a public-private key pair. I don't want to check this into source control because it will be accessible by too many people. Since this is GAE I can't use the build system to write the keys to the file system of the server.
Is there a known best practice for this?
My first thought was does Jenkins provide a way to manage keys securely? I know I can just copy the keys to a location on the jenkins server and copy them into the build but this project will be used by third party teams so I need to provide a UI based solution in jenkins. I did not find any relevant plugin but I would like to make sure there isn't a better way before writing my own.
There are of course several approaches to this. I believe certificates are a concern of admins, not developers.
What we do is have custom admin pages where we upload certificates to blobstore under separate namespace. Then we have an internal "service" (just a simple factory) so that other pieces of code can retrieve certs.
If you are happy to use a cloud based Jenkins, we (CloudBees) have an oauth based solution at appengine.cloudbees.com
You could roll your own. It is not excessively tricky. You will need to
Register with google's api console to get a client key and secret and define the endpoints that your app will show up as
Write some way if feeding those credentials to your Jenkins build. I would recommend using the credentials plugin
Either write a build wrapper that exposes the refresh token to your build (python sdk deployment) or exposes the access token (java sdk... Got to love that the two sdks do the same thing in different ways)
Or use our free service ;-)
Related
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.
I am curious to know of available options, that a developer can use to secure sensitive information inside the mobile application. This is to prevent anyone from breaking the app and use keys for some nefarious purposes. Example of sensitive data includes passwords of APIs, which app can use seamlessly in the background to retrieve data.
Code obfuscation can help but cannot prevent from stealing the information;
Local storage options such as nativescript-couchbase or nativescript-secure-storage -if my understanding is correct- depends on feeding the information manually after installing the app. But the information needs to be available inside the app at the time of shipping.
OAuth is not an option as it requires the user to login in order to receive the tokens. JWT is neither an option, as the APIs are protected just using basic authentication.
I am using nativescript/angular2 but i would appreciate any generic simple yet effective ideas..
I think you are looking for obfuscation here, securing the information within your source code. By default {N} has uglify plugin configured within webpack, it gives the basic obfuscation.
There is Jscrambler support which is paid.
Also, speaking of Sqlite, there is commercial version of the plugin that supports encryptions but I haven't tried it personally. You may feed your data into it and pack your db at build time then install the db on first launch.
How to use external CyberArk vault to store credentials in free version Jenkins?
Here you can find info regarding the standard jenkins credentials plugin - that provides an API for external storage.
But after digging a while on the net, I’ve found that:
1. Cyberark vault is available on Cloudbees Jenkins only
2. HarshiCorp vault plugin is available for free
3. Here is a nice example how wrong permissions policy can lead to exposing all credentials. I tried it, works like a magic! :)
You really don't want to store credentials (or any sensitive secret, really) in Jenkins. It's not a vault and should never be used as one. Otherwise you'll end up with your Jenkins servers becoming a major target for attackers.
Instead, integrate your Jenkins pipelines to pull secrets securely into executors only when needed, and discarded when the build/test job is done. This is easily done with something like Summon, which is integrated with many vaults already, including Conjur (which is a CyberArk product, too). Both are open source offerings.
This blog post describes an approach to integrating Jenkins with a vault along the lines of what I've described above.
Appears that CyberArk released Jenkins plugin which supports that scenario:
https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Integrations/jenkins.htm
You might want to look at https://github.com/tmobile/t-vault .
This will eliminate the need to manage policies. You could create one safe per project folder or job in jenkins.
You can create approles and grant access to safe for the approle. Each project can use corresponding approle. You can grant access to individuals to the safe as well. Users can then use the webui to author and update the secrets.
I have an standard appengine app currently running. I am currently developing another flask app which will use flexible runtime. I am wondering is it possible for me to have both apps in same project?
Yes, it is possible, with each of your "applications" being implemented as separate services/modules in the same GAE app. Services/modules offer complete code isolation, see Comparison of service isolation and project isolation.
See also: Custom runtime for non-flexible environment app?
There is an even easier way to do this that doesn't require creating a separate service :)
Since you are only developing your second application, you do not need to set it as the default version to serve traffic to the public. You only need to access it yourself, (or perhaps whoever you give the URL to). The only drawback really is that you will not be able to access your project at the default url, usually .appspot.com
Therefore, you can simply deploy your flexible app engine project, but make sure you don't give it any traffic sharing or promote it to the main version!! You can then access your version simply by clicking on the version in the google cloud console, or by visiting http://-dot-.appspot.com/ (It was not possible to access individual versions like this for flexible for quite some time, but this has now been resolved.)
I'm working on a project with Google App Engine. I am using continuous integration via Travis, and wish to be able to deploy directly from it. Due to a bug that will not be resolved directly, I can't rely on Travis' built-in GAE deployment, so I basically have to use mvn appengine:update manually. This requires me navigate to a generated URL and manually paste to the terminal an authentication code, which I can't do in automated builds.
It was suggested to me, however, that I do some Unix magic instead. While I can easily pick out the URL I need to navigate to from grep, I still need to log in to Google with my credentials in order to actually get the authentication code (which I can then grep out and pipe to the deployment program).
Given that, how do I log in to Google with my credentials, using only curl or similar command-line utilities?
I've accomplished similar things in the past using Service Accounts. These are likely a good fit for your problem.
Service Accounts will allow you to authenticate and upload your app without manual intervention.
Overview
A Service Account will allow you to do "passwordless" authentication like you may already do with ssh, and git, etc. by setting up your keys. This will remove the requirement that you log in manually, or follow the road to madness by trying to do a "manual" login automatically.
There are basically two steps:
Create your service account and key (with the right permissions)
Use that credential instead of what you're doing now
Resources
I think it's better to give a list of resources than concrete instructions since it's basically impossible to express concisely (even though it's a simple process, there's bound to be a lot of little things that annoy), everyone's requirements will be slightly different, and Google is likely to change the process at some point.
Using the Google Cloud Platform Console for App Engine | Permissions
Using OAuth 2.0 for Server to Server Applications
Setting up OAuth 2.0 | Service Accounts
gcloud auth activate-service-account
Hopefully that's enough to get you headed in the right direction.
Note
You'll likely have to spend some time looking at your .appcfg_oauth2_tokens_java and sorting out a variety of other annoyances, but I believe that this approach is the best way to solve your problem.
It sounds like you have a pretty straight-forward setup and that a Service Account alone will get you there, but if you need to get a little weird, the App Engine Admin API is always there.