Google 应用引擎:隐藏 Rails 密钥的最佳实践?
Google app engine: Best practice for hiding Rails secret keys?
我正在将我的 Rails 应用程序部署到 GAE,其代码存储在 github.
显然,我需要隐藏我的密钥和数据库密码。
在 Heroku 中,我可以使用 Heroku GUI 非常轻松且很好地在环境变量中设置它们,因此它不会出现在任何源代码或数据库中。
GAE 呢?
我无法在 app.yaml 中设置它们,因为:
- .gitignore 不是一个选项:即使我通过 .gitignore 隐藏 app.yaml 文件或替代 json 文件,我也必须将它保存在我的本地计算机中。意思就是只有我可以部署,我得自己做备份。这太可怕了。
- 有人说我可以在数据库中存储秘密值。但是我也想隐藏数据库密码。
有什么想法吗?
存储此信息最安全的方法是使用 project metadata. On a Flexible/ManagedVM environment you can access the metadata via a simple http request。
来自 google 博客 post:
With Compute Engine, Container Engine, and Managed VMs, there is a magic URL you can CURL to get metadata.
ManagedVMs 是现在所谓的旧名称 'AppEngine Flexible Environment'。由于您说您在 App Engine 上使用 Ruby,因此您必须使用 Flexible/ManagedVMs。因此你应该能够使用这些 'magic URLs'.
因此,要在 Ruby 中获取名为 mysecret
的应用程序机密,您可以这样做:
Net::HTTP.get(
URI.parse('http://metadata.google.internal/computeMetadata/v1/project/attributes/mysecret'))
(对于@joshlf)以下是在 Python 中访问 AppEngine 标准环境中的 项目 元数据的方法:
# 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')
我在 中解决了这个问题。本质上,您可以在 app.yaml
旁边创建一个 credentials.yaml
文件并将其导入 app.yaml
。这将允许您将凭据指定为 ENV 变量,同时保留忽略 git 中文件的能力。 includes:
标签允许您在 app.yaml
.
中导入一组文件
示例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
我正在将我的 Rails 应用程序部署到 GAE,其代码存储在 github.
显然,我需要隐藏我的密钥和数据库密码。
在 Heroku 中,我可以使用 Heroku GUI 非常轻松且很好地在环境变量中设置它们,因此它不会出现在任何源代码或数据库中。
GAE 呢? 我无法在 app.yaml 中设置它们,因为:
- .gitignore 不是一个选项:即使我通过 .gitignore 隐藏 app.yaml 文件或替代 json 文件,我也必须将它保存在我的本地计算机中。意思就是只有我可以部署,我得自己做备份。这太可怕了。
- 有人说我可以在数据库中存储秘密值。但是我也想隐藏数据库密码。
有什么想法吗?
存储此信息最安全的方法是使用 project metadata. On a Flexible/ManagedVM environment you can access the metadata via a simple http request。
来自 google 博客 post:
With Compute Engine, Container Engine, and Managed VMs, there is a magic URL you can CURL to get metadata.
ManagedVMs 是现在所谓的旧名称 'AppEngine Flexible Environment'。由于您说您在 App Engine 上使用 Ruby,因此您必须使用 Flexible/ManagedVMs。因此你应该能够使用这些 'magic URLs'.
因此,要在 Ruby 中获取名为 mysecret
的应用程序机密,您可以这样做:
Net::HTTP.get(
URI.parse('http://metadata.google.internal/computeMetadata/v1/project/attributes/mysecret'))
(对于@joshlf)以下是在 Python 中访问 AppEngine 标准环境中的 项目 元数据的方法:
# 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')
我在 app.yaml
旁边创建一个 credentials.yaml
文件并将其导入 app.yaml
。这将允许您将凭据指定为 ENV 变量,同时保留忽略 git 中文件的能力。 includes:
标签允许您在 app.yaml
.
示例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