8

I am deploying my Rails app to GAE, whose codes are stored in github.

Obviously, I need to hide my secret key and database password.

In Heroku, I can set them in environment variables very easily and nicely using Heroku GUI, so it won't appear in any source code or database.

What about GAE? I cannot set them in app.yaml because:

  1. .gitignore is not an option: Even I hide app.yaml file or alternative json file by .gitignore, I have to save it in my local computer. It means that Only I can deploy, and I have to do backup by myself. This is terrible.
  2. Someone says that I can store secret values in database. But I want to hide database password too.

Any idea?

Shinji Otani
  • 83
  • 1
  • 5
  • I encrypt environment variables in `.env` files with GPG and use [dotgpg](https://github.com/ConradIrwin/dotgpg) to manage them. You could encrypt your `app.yaml` file and store it in the repository. – p4sh4 Dec 05 '16 at 07:47
  • @p4sh4 Thanks for your comment. The idea is great, but have you ever tried your idea with CI tool (like Circle CI)? – Shinji Otani Dec 05 '16 at 09:30
  • Yes, CircleCI in particular - but I added the environment variables that I needed for testing and deployment to CircleCI itself since it is possible to do so in a secure way, and I don't decrypt the `.env` file there. – p4sh4 Dec 06 '16 at 12:13

2 Answers2

5

I addressed this problem in an answer to a similar question. Essentially, you can create a credentials.yaml file alongside your app.yaml and import it in app.yaml. This will allow you to specify your credentials as ENV variables while retaining the ability to ignore the file in git. The includes: tag allows you to import an array of files in your app.yaml.

Example app.yaml:

runtime: go
api_version: go1

env_variables:
  FIST_VAR: myFirstVar

includes:
- credentials.yaml

credentials.yaml:

env_variables:
  SECOND_VAR: mySecondVar
  API_KEY: key-123
Raees Iqbal
  • 2,160
  • 1
  • 18
  • 15
4

The most secure way to store this info is using project metadata. On a Flexible/ManagedVM environment you can access the metadata via a simple http request.

From the google blog post:

With Compute Engine, Container Engine, and Managed VMs, there is a magic URL you can CURL to get metadata.

ManagedVMs are the old name for what is now called 'AppEngine Flexible Environment'. Since you say you are using Ruby on App Engine you must be using Flexible/ManagedVMs. Therefore you should be able to use these 'magic URLs'.

So to get an application secret called mysecret in Ruby you might do:

Net::HTTP.get(
    URI.parse('http://metadata.google.internal/computeMetadata/v1/project/attributes/mysecret'))

(For @joshlf) Here's how to access project metadata on AppEngine Standard Environment in Python:

# Note that the code will not work on dev_appserver, 
# you will need to switch to some other mechanism 
# for configuration in that environment
# Specifically the project_id will resolve to something
# compute engine API will treat as invalid

from google.appengine.api import app_identity
from googleapiclient import discovery
from oauth2client.client import GoogleCredentials

compute = discovery.build(
    'compute', 'v1', credentials=GoogleCredentials.get_application_default())

def get_project_metadata(metadata_key):
    project_id = app_identity.get_application_id()
    project = compute.projects().get(project=project_id).execute()
    for entry in project['commonInstanceMetadata']['items']:
        if entry['key'] == metadata_key:
            return entry['value']
    return None

get_project_metadata('my_key')
Frank Wilson
  • 3,192
  • 1
  • 20
  • 29
  • thanks. Isn't project metadata working with GCE, not GAE? Or Are you talking about Cloud Datastore? – Shinji Otani Dec 05 '16 at 09:39
  • Thanks for updating. I will try metadata and add what I felt with it. – Shinji Otani Dec 05 '16 at 10:37
  • Yes, I can use metadata. Thanks. But I still feel little bit painful in this way compared to Heroku (where we can define env variables very easily) and AWS (you can set them in the server) though... – Shinji Otani Dec 06 '16 at 03:03
  • Did you figure out how to access metadata from Google App Engine? I figured out how to access instance metadata, but not project-wide metadata, from the Google Cloud Shell console. – joshlf Dec 06 '16 at 07:27
  • What I found is the way to access instance metadata. It looks like Google say that the metadata values will not go outside of the instance (in security section of https://cloud.google.com/compute/docs/storing-retrieving-metadata). – Shinji Otani Dec 06 '16 at 07:58
  • 1
    @joshlf I updated my answer with some code that will work in the standard environment. You didn't say what language you were using so I assumed Python. You might want to cache the result if you access the metadata frequently. – Frank Wilson Dec 06 '16 at 11:46
  • @joshlf By the way you can access project wide metadata on the cli with: `gcloud compute project-info describe --format 'value(commonInstanceMetadata.my_key)'` – Frank Wilson Dec 06 '16 at 12:07