

# SEC02-BP03 安全地存储和使用密钥
<a name="sec_identities_secrets"></a>

 工作负载需要能够自动向数据库、资源和第三方服务证明其身份。这是使用秘密访问凭证（如 API 访问密钥、密码和 OAuth 令牌）完成的。使用专门构建的服务来存储、管理和轮换这些凭证，有助于降低这些凭证泄露的可能性。

 **期望结果：**实施安全管理应用程序凭证的机制来实现以下目标：
+  确定工作负载需要哪些密钥。
+  尽量使用短期凭证代替长期凭证，从而减少所需长期凭证的数量。
+  建立安全存储并自动轮换剩余的长期凭证。
+  审核对工作负载中存在的密钥的访问。
+  持续监控，验证开发期间没有在源代码中嵌入任何密钥。
+  降低凭证被无意中泄露的可能性。

 **常见反模式：**
+  不轮换凭证。
+  将长期凭证存储在源代码或配置文件中。
+  在未加密状态下静态存储凭证。

 **建立此最佳实践的好处：**
+  对存储的凭证进行静态和传输中加密。
+  通过 API 来把关对凭证的访问（可将 API 看作*凭证自动售货机*）。
+  审核和记录对凭证的访问（包括读和写）。
+  关注点分离：凭证轮换由一个单独的组件执行，该组件可与架构的其余部分隔离开来。
+  密钥自动按需分发给软件组件，并在中心位置进行轮换。
+  可以精细地控制对凭证的访问。

 **在未建立这种最佳实践的情况下暴露的风险等级：**高 

## 实施指导
<a name="implementation-guidance"></a>

 过去，用于对数据库、第三方 API、令牌和其他密钥进行身份验证的凭证，可能已嵌入到源代码或环境文件中。AWS 提供了几种机制来安全地存储这些凭证，自动轮换凭证，并审核凭证的使用情况。

 妥善管理密钥的方法是遵循相关指导，正确地删除、替换和轮换密钥。最安全的凭证是不必存储、管理或处理的凭证。某些凭证可能不再是正常运行工作负载所必需的，可以安全地删除。

 对于仍然是正常运行工作负载所必需的凭证，可能有机会用临时或短期凭证替换长期凭证。例如，相较于对 AWS 秘密访问密钥进行硬编码，不妨考虑使用 IAM 角色将长期凭证替换为临时凭证。

 可能无法删除或替换某些长期密钥。这些密钥可以存储在 [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 等服务中，在其中得到集中存储、管理和定期轮换。

 对工作负载的源代码和配置文件进行审计，可以发现许多类型的凭证。下表总结了处理常见凭证类型的策略：


|  凭证类型  |  描述  |  建议采取的策略  | 
| --- | --- | --- | 
|  IAM 访问密钥  |  用于在工作负载内代入 IAM 角色的 AWS IAM 访问密钥和私有密钥  |  替换：改用分配给计算实例（例如 [Amazon EC2](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html) 或 [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)）的 [IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios.html)。为了与需要访问 AWS 账户中资源的第三方实现互操作性，请询问他们是否支持 [AWS 跨账户访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html)。对于移动应用程序，请考虑通过 [Amazon Cognito 身份池（联合身份）](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html)使用临时凭证。对于在 AWS 之外运行的工作负载，请考虑使用 [IAM Roles Anywhere](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/introduction.html) 或 [AWS Systems Manager 混合激活](https://docs.aws.amazon.com/systems-manager/latest/userguide/activations.html)。对于容器，请参阅 [Amazon ECS 任务 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html)或 [Amazon EKS 节点 IAM 角色](https://docs.aws.amazon.com/eks/latest/userguide/create-node-role.html)。 | 
|  SSH 密钥  |  用于登录 Linux EC2 实例的 Secure Shell 私有密钥，可手动登录或作为自动流程的一部分登录  |  替换：使用 [AWS Systems Manager](https://aws.amazon.com/blogs/mt/vr-beneficios-session-manager/) 或 [EC2 Instance Connect](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Connect-using-EC2-Instance-Connect.html)，通过 IAM 角色提供对 EC2 实例的编程访问权限和人类访问。 | 
|  应用程序和数据库凭证  |  密码 – 纯文本字符串  |  轮换：将凭证存储在 [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 中，并尽量建立自动轮换机制。 | 
|  Amazon RDS 和 Aurora 管理数据库凭证  |  密码 – 纯文本字符串  |  替换：使用 [Secrets Manager 与 Amazon RDS 集成](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-secrets-manager.html)或 [Amazon Aurora](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-secrets-manager.html)。此外，在某些应用场景中，一些 RDS 数据库类型可以使用 IAM 角色代替密码（有关更多详细信息，请参阅 [IAM 数据库身份验证](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html)）。 | 
|  OAuth 令牌  |  密钥令牌 – 纯文本字符串  |  轮换：将令牌存储在 [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 中并配置自动轮换。 | 
|  API 令牌和密钥  |  密钥令牌 – 纯文本字符串  |  轮换：存储在 [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 中，并尽量建立自动轮换机制。 | 

 一种常见的反模式是在源代码、配置文件或移动应用程序中嵌入 IAM 访问密钥。当需要 IAM 访问密钥与 AWS 服务通信时，请使用[临时（短期）安全凭证](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)。可以通过 [EC2 实例的 IAM 角色](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)、Lambda 函数的[执行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)、移动用户访问的 [Cognito IAM 角色](https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html)和 IoT 设备的 [IoT Core 策略](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html)，提供这些短期凭证。与第三方进行交互时，最好[将访问权限委托给 IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html)，授予对账户资源的必要访问权限，而不是配置 IAM 用户并向第三方发送该用户的秘密访问密钥。

 在许多情况下，工作负载需要存储与其他服务和资源进行互操作所必需的密钥。[AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 旨在安全地管理这些凭证，以及 API 令牌、密码和其他凭证的存储、使用和轮换。

 AWS Secrets Manager 提供五个关键功能，确保敏感凭证的安全存储和处理：[静态加密](https://docs.aws.amazon.com/secretsmanager/latest/userguide/security-encryption.html)、[传输中加密](https://docs.aws.amazon.com/secretsmanager/latest/userguide/data-protection.html)、[全面审核](https://docs.aws.amazon.com/secretsmanager/latest/userguide/monitoring.html)、[精细访问控制](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access.html)和[可扩展凭证轮换](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html)。AWS 合作伙伴提供的其他密钥管理服务或提供类似功能和保证的本地开发的解决方案，也可以接受。

 在检索密钥时，可以使用 Secrets Manager 客户端缓存组件来缓存密钥，以备将来使用。检索已缓存密钥比从 Secrets Manager 中检索密钥的速度要快。此外，由于调用 Secrets Manager API 会产生费用，因此使用缓存可以降低成本。有关检索密钥的所有方法，请参阅 [Get secrets](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets.html)。

**注意**  
 某些语言可能要求您实施自己的内存加密来进行客户端缓存。

### 实施步骤
<a name="implementation-steps"></a>

1.  使用自动化工具（如 [Amazon CodeGuru](https://aws.amazon.com/codeguru/features/)）识别包含硬编码凭证的代码路径。

   1.  使用 Amazon CodeGuru 扫描代码存储库。审核完成后，在 CodeGuru 中按 Type=Secrets 进行筛选来查找有问题的代码行。

1.  识别可以删除或替换的凭证。

   1.  识别不再需要的凭证并标明要删除。

   1.  对于嵌入到源代码的 AWS 私有密钥，将其替换为与必要资源相关的 IAM 角色。如果部分工作负载在 AWS 之外，但需要 IAM 凭证才能访问 AWS 资源，请考虑采用 [IAM Roles Anywhere](https://aws.amazon.com/blogs/security/extend-aws-iam-roles-to-workloads-outside-of-aws-with-iam-roles-anywhere/) 或 [AWS Systems Manager 混合激活](https://docs.aws.amazon.com/systems-manager/latest/userguide/activations.html)。

1.  对于其他需要使用轮换策略的第三方、长期密钥，请将 Secrets Manager 集成到代码中，以便在运行时检索第三方密钥。

   1.  CodeGuru 控制台可以使用发现的凭证[在 Secrets Manager 中自动创建密钥](https://aws.amazon.com/blogs/aws/codeguru-reviewer-secrets-detector-identify-hardcoded-secrets/)。

   1.  将 Secrets Manager 的密钥检索集成到应用程序代码中。

      1.  无服务器 Lambda 函数可以使用与语言无关的 [Lambda 扩展](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets_lambda.html)。

      1.  对于 EC2 实例或容器，AWS 用几种流行的编程语言提供了示例[客户端代码，用于从 Secrets Manager 检索密钥](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets.html)。

1.  定期检查代码库并重新扫描，验证代码中没有添加新的密钥。

   1.  考虑使用诸如 [git-secrets](https://github.com/awslabs/git-secrets) 之类的工具，防止向源代码存储库提交新的密钥。

1.  [监控 Secrets Manager 活动](https://docs.aws.amazon.com/secretsmanager/latest/userguide/monitoring.html)，发现意外使用、不适当的密钥访问或试图删除密钥的迹象。

1.  减少人类接触凭证的机会。将读取、写入和修改凭证的权限仅授予专用于此目的的 IAM 角色，并仅向一小部分操作用户提供代入该角色的权限。

## 资源
<a name="resources"></a>

 **相关最佳实践：**
+  [SEC02-BP02 使用临时凭证](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_unique.html) 
+  [SEC02-BP05 定期审计和轮换凭证](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_audit.html) 

 **相关文档：**
+  [AWS Secrets Manager 入门](https://docs.aws.amazon.com/secretsmanager/latest/userguide/getting-started.html) 
+  [身份提供程序和联合身份验证](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html) 
+  [Amazon CodeGuru 推出 Secrets Detector](https://aws.amazon.com/blogs/aws/codeguru-reviewer-secrets-detector-identify-hardcoded-secrets/) 
+  [AWS Secrets Manager 如何使用 AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/services-secrets-manager.html) 
+  [Secret encryption and decryption in Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/security-encryption.html) 
+  [Secrets Manager 博客系列文章](https://aws.amazon.com/blogs/security/tag/aws-secrets-manager/) 
+  [Amazon RDS 宣布与 AWS Secrets Manager 集成](https://aws.amazon.com/about-aws/whats-new/2022/12/amazon-rds-integration-aws-secrets-manager/) 

 **相关视频：**
+  [Best Practices for Managing, Retrieving, and Rotating Secrets at Scale](https://youtu.be/qoxxRlwJKZ4) 
+  [Find Hard-Coded Secrets Using Amazon CodeGuru Secrets Detector](https://www.youtube.com/watch?v=ryK3PN--oJs) 
+  [Securing Secrets for Hybrid Workloads Using AWS Secrets Manager](https://www.youtube.com/watch?v=k1YWhogGVF8) 

 **相关讲习会：**
+  [Store, retrieve, and manage sensitive credentials in AWS Secrets Manager](https://catalog.us-east-1.prod.workshops.aws/workshops/92e466fd-bd95-4805-9f16-2df07450db42/en-US) 
+  [AWS Systems Manager Hybrid Activations](https://mng.workshop.aws/ssm/capability_hands-on_labs/hybridactivations.html) 