为什么在使用“应用平台”时将 API 密钥存储在 DigitalOceans API“环境变量”选项中是安全的? 第 2 点和第 3 点:第 4 点:第 5 点:第 6 点:

如何解决为什么在使用“应用平台”时将 API 密钥存储在 DigitalOceans API“环境变量”选项中是安全的? 第 2 点和第 3 点:第 4 点:第 5 点:第 6 点:

我正在设置一个 NodeJS 后端,它需要保存一些 API 密钥,以便与 Firebase 联系以对用户进行身份验证。

我已经能够发布后端并成功从其上的 API 端点获得 HTTP 回复。我使用 Express 来运行 NodeJS API。

现在我希望 NodeJS API 充当我的用户和数据库联系点。但我不确定在哪里安全地存储项目的 API 密钥。因为我对这种安全性比较陌生。

所以,我在谷歌上搜索,发现有人说 .env 文件不是存储 API 密钥的安全位置。然而在 DigitalOcean documentation 上,它说如下:

环境变量是存储敏感信息(例如 API 密钥)或需要从应用中的任何位置全局访问的信息(例如版本号或硬编码路径)的绝佳位置。

所以我的问题是,DigitalOcean 会说将 API 密钥存储在环境变量中是安全的原因是什么,而许多其他来源说它不是。这是因为危险在于文件的可访问性,然后 DigitalOcean 以某种方式保护了文件? 我注意到他们有一个你可以勾选的“秘密”布尔框,它表示它不会出现在控制台中。但一般人是否也完全无法访问它?

我主要关心的是防止黑客或怀有恶意的人访问 API 密钥。我不担心有合法访问权限的人会滥用它,只担心没有合法访问权限的人会滥用它。

期待您的见解。

解决方法

我将按照以下顺序(从不太安全到最安全)对存储机密的安全性进行排名:

  1. 将它们直接存储在您的代码中(非常非常糟糕)
  2. 将它们存储在环境变量中
  3. 将它们存储在磁盘上的文件中
    • 可以设置访问权限,例如谁能看懂
    • 如果您将内容加载到 env vars 中,它将与 Point 2
    • 没有什么不同
  4. 将它们存储在对象存储(AWS S3、Google Cloud Storage)中
  5. 使用机密管理器(AWS、GCP 机密管理器)存储它们
  6. 使用 IAM(实际上并不是一个存储机密的地方,而是一种使用上述方法控制谁可以访问机密的方法)。

精心设计:

第 2 点和第 3 点:

如果您的系统遭到入侵,points 2 and 3 之间的区别就会变得模糊不清。在这种情况下,如果攻击者具有 root 访问权限,他/她可以读/写/删除/更改所有内容,因此 point 3 将失败。对于 point 2,攻击者可以通过 3 种方法访问环境变量:

根据this post中的@phmmmer

  1. 进程的运行环境 当进程运行时,可以通过/proc/$PID/environ > > 访问该进程的环境变量。但是,只有拥有 进程或 root 可以访问该文件。

  2. 环境变量的来源 如果您使用的是 init 脚本,并且变量存储在该 init 脚本中,则 变量当然可以通过阅读该脚本获得。

或者如果环境变量来自其他地方,那么 无论在哪里。

  1. 'ps' 输出 是的,我知道我说的是 2,在任何像样的系统中,它都是 2。但是如果管理员不知道他在做什么,那就是 有可能开辟第三条大道。

如果进程是通过类似 sh -c 'cd /foo/bar; POP=tart /my/executable' 的方式启动的,那么该 sh 进程将在 ps 中可见: 如果进程是通过类似 sh -c 'cd /foo/bar; POP=tart /my/executable' 的方式启动的,那么该 sh 进程将在 ps 中可见:


$ ps ax | grep POP phemmer   3085  14   5  0.0  0.0 SN         00:00
sh -c cd /; POP=tart sleep 10```

第 4 点:

您可以将机密作为对象存储在对象存储中,并在部署或启动期间下载它们。大多数对象存储都提供日志记录功能,因此您还可以监控您的机密如何被使用以及谁在使用它们。注意:Point 4 很好,当且仅当您正确配置了 IAM 权限。否则,它与 Point 2 没有区别,尽管现在您是从远程位置获取文件。

第 5 点:

您的应用程序可以使用所有机密管理器的 API 以使用机密。除了在内存中,您的秘密不会存储在本地的任何地方。是的。你也可以加密你的记忆,你可以在this post

中阅读更多

第 6 点:

IAM 或身份和访问管理用于在正确的时间向正确的人/用户/应用程序授予对正确资源的正确访问权限。它不是秘密存储,但可用于管理对秘密存储的访问。

所以回答你的问题:

"Environment variables are excellent places to store sensitive information" 可能是 DO 的夸大其词。但它们提供的不仅仅是将您的敏感信息存储在环境变量中并将它们留在那里。

在您在问题中提到的文档的 next post "How to Use Environment Variables in App Platform" 中,DO 确实提供了有关环境变量的某些级别的访问控制和加密:

  1. 运行时变量
    • 在应用创建过程中
    • 创建应用后
  2. 构建时间变量
  3. 环境变量中的可绑定变量
    • 应用范围的变量
    • 特定于组件的变量

因此,当人们说使用环境变量存储敏感信息不安全时,他们中的大多数人都在谈论没有访问控制和加密的普通环境变量。在这种情况下,将您的 API 密钥存储在那里显然是不安全的。应使用普通的普通环境变量来存储端口号、生产环境或其他非敏感信息等信息。

我使用了一些帖子作为此答案的参考:

  1. 5 ways to manage serverless secrets,ranked best to worst
  2. A comprehensive guide to managing secrets in your Terraform code
  3. DigitalOcean: How to Use Environment Variables in App Platform
,

同意之前的帖子。一个好的做法是考虑“如果您的系统受到损害,它们会在您的系统上以 ROOT 身​​份运行”。如果您可以像 sudo 一样做任何事情 - 假设他们也可以。

我想添加的一项是养成为 dev / test / prod / 和每个本地开发人员使用唯一 API 密钥的习惯。我知道这似乎很明显,但我已经看到很多情况下,人们在生产中做了很棒的事情,但在开发中重复使用相同的 API 密钥,甚至允许开发人员在他们的本地机器上使用相同的生产 API 密钥,而它不是受到同样严格的保护。

同样使用上述 IAM 可以很好地确保限制访问,但如果您沿着这条路线走下去,请确保您愿意让自己更难在 Azure、AWS、GCP 环境之间移动。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-