什么是秘密?
一个秘密就是一个敏感信息。 例如,可用于访问保密系统的 API 密钥,密码或任何类型的凭证。
通过使用私钥,您可以在构建应用程序时向受保护资源进行认证。 例如,当您尝试访问外部服务 API 时,将要求您提供唯一凭证。 提供凭证后,外部服务可以了解您是谁以及您是否有权与该凭证进行交互。
要了解有关秘密的一般特征的更多信息,请查看以下视频。
视频文字记录
如何确保安全地存储私钥,以避免 DevOps 工作流程中的数据泄露和混乱?
大家好,我是 IBM Cloud 团队的 Alex Greer,在开始之前,请确保立即喜欢并订阅。
什么是秘密?
私钥是一种数字凭证,用于允许实体对服务进行通信和执行操作。 此离散信息可确保该访问点的安全。 让我们看看这个范式是如何存在的。
让我们先从需要访问某种服务的实体开始。 我们现在会让它变得有点模棱两可,但有些服务。 要与服务进行正确的沟通,并能采取它需要的行动来完成它的工作,这个实体就要需要向服务传达两件事: 一,是谁,让服务能理解什么或谁在与它互动。 第二,它必须知道它应该在其服务的上下文中授予的一组许可权。 通过这些操作,服务现在可以正确允许该实体与这些实体进行交互。 我们如何实现这种互动,与我们称之为“秘密”的东西。
现在,通过建立此动态,让我们以用户为例。 对于用户来说,我们会说这里的这个用户是我们的实体,我们会在这里说我们的服务 -- 让我们说它是一个开发者,他们碰巧需要读或写访问权。 他们正在与开发存储库进行交互以执行此操作。 为了再次获得该访问权,返回到需要时,我们已获得授权和许可。 它将如何进行通信,尤其是在这种情况下,通过向其提供用户凭证来进行通信。 现在,该用户可以通过完成其工作所需的方式与开发存储库进行交互。
现在,从一个云原生应用案例来看,我们有许多微服务必须相互对话。 所以,让我们来看看这个。 让我们将其称为服务 "A",该服务需要与名为 "DB" 的数据库进行交互,并获取完成其工作所需的特定信息。 它需要的,以这里的秘密的形式,就是我们所说的“DB 配置”。 同样,这个 DB 配置将允许它与服务进行正确的通信,方法是说,这是我的身份,这是我来这里完成的任务。
但现在我们的数据库配置中有我们的用户凭证作为私钥的示例,我们意识到如果这些凭证落入错误的手中,就可以在这里创建漏洞。 这就是为什么在我们构建更多应用和微服务的同时,建立一个集中的场所来管理所有这些事物非常重要。 随着我们拥有更多的这些,问题变得更加复杂。 如果落入了错误的手中,该如何保护? 我们该如何阻止它到达那个地步? 如何隔离这些数据?
当我们研究这可能造成的损害时,我们正在寻找数百万美元的资金,比如数据泄露。 在开发人员运营方面,如果你没有正确管理这些,就连一个糟糕的参与者都没有参与的案例都忘记了,但让团队使用这一点可能令人困惑。 因此,我们需要做的是确保我们再次将其存储为不正确的集中存储,以便我们能够以正确的方式利用这些秘密,并使它们能够与服务进行正确的通信。
好,现在,让我们以一个更复杂的例子来看下一层洋葱。
现在,让我们回到企业开发人员 Jane。 Jane-我们这里的 "E dev"-需要再次访问她先前提到的开发存储库。 让我们继续对此进行调用,也许是 GitHub。 所以她需要能够做的就是有写访问权,所以她需要请求能够让她访问该角色的信息。 这就是秘密经理服务以完美,互补的方式出现的地方。
私钥管理器服务可以以集中方式安全地存储这些凭证以及其他类型的私钥,以便她能够访问或可能访问其他服务,就像我们稍后会看到的那样。 但完成后,让她安心的是,她的用户凭证是安全存储的,现在她可以担心向服务认证并完成她的工作,因为私钥管理员会为她处理这件事。
但是,对于私钥管理器服务而言,真正重要的是与云服务提供商的 IAM 或身份和访问管理服务进行交互。 IAM 将是真相的源泉,允许秘密管理器首先验证她的身份,以便将其传递到 GitHub,其次还允许她根据 IAM 服务中的范例获得正确的角色集。 有了这个,我们现在就明白了用户获得正确的许可,能够访问他们选择的服务的工具,并且能够在使用 secret manager 服务的背景下做到这一点。
现在,让我们来看看一个服务与另一个服务交互的方式,以及数据泄露可能有害的地方。
让我们来看看我们的服务到服务示例。 我们首先要做的是贷款申请。 这款借贷应用将会希望请求许可权,以便能够访问-同样,我们之前讨论的是一个数据库。 让我们具体一点: 它需要访问的这个数据库是数据库内的一个给定表,有必要的信息给它的模型,以便能够对他们是否想要单独提供一个消费者做出判断。 因此,我们将此称为概要文件数据库。 在这里,我们有一个概要文件 DB,我们知道我们要授予的一组许可权将是表 A 的读许可权。 同样,我们将在何处存储最终将授予我们访问权的秘密,从而使我们能够访问认证,并最终访问我们在这里需要的一组许可权? 因此,这将再次成为所提供的密钥管理器服务,并且该服务需要再次与 Cloud IAM 进行对话。 既然我们已经建立了这个,我们这里有什么类型的凭证? 我们拥有的凭证称为数据库配置。 让我们来思考一下我们刚刚走过的场景: 这个 DB 配置允许这个借贷应用程序一个服务能够拥有读访问权,或者能够从一个数据库中的给定表中获取一组特定的信息,该数据库中有一些 IP 数据和其他一些高度敏感的信息。 因此,在这些 DB 配置未正确存储或其存储的服务受到损害的场景中,我们最终得到的是对提供商来说是一个相当灾难性的场景,因为这个借贷应用程序的这个服务的提供商随后必须去告诉它的客户,一个糟糕的参与者能够利用它对其 DB 配置的错误访问。 而且,该数据库配置最终允许该不良参与者窃取他们的数据,并对该客户执行他们想要的任何操作。 我们可以采取的措施是将其存储在安全的位置,否则,不良参与者将无法访问数据,而且您可以获得企业所需的数据隔离级别。 这就是我们拥有秘密经理服务的地方。
同样,私钥管理器服务有助于确保私钥的安全存储,这样您就不必担心来自上次凭证或其他类型私钥的数据泄露。 最终,这将使您在执行 DevOps 操作时更有效地管理私钥。
谢谢您。 如果您有疑问,请给我们丢一行。 如果您希望将来看到更多类似这样的视频,请点赞和订阅,不要忘记您可以通过 IBM Cloud Labs (这是免费的基于浏览器的交互式 Kubernetes 实验室) 发展技能并获得徽章。
使用不同类型的私钥
在 Secrets Manager 中创建的私钥可以是静态私钥,也可以是动态私钥。 静态私钥在私钥创建或轮换时强制实施其到期日期和时间。 相反,动态私钥这是一个唯一值,例如密码或 API 密钥,它是动态创建的,并租赁给需要访问受保护资源的应用程序。 动态私钥到达其租赁结束后,将撤销对受保护资源的访问权,并自动删除该私钥。 在读取或访问其私钥数据时强制实施其到期日期和时间。
Secrets Manager 进一步按其常规用途或功能对静态和动态私钥进行分类。 例如,每个私钥类型都由程序名标识,例如 username_password
。 如果您希望使用 Secrets Manager API 或 CLI 来管理私钥,那么可以使用这些程序名根据私钥类型对私钥运行操作。
查看下表以了解可以使用服务创建和管理的静态和动态私钥的类型。
类型 | 程序名 | 种类 | 描述 |
---|---|---|---|
任意私钥 | arbitrary |
静态 | 敏感数据 (包括可用于访问应用程序或资源的任何类型的结构化或非结构化数据) 的任意片段。 |
[IAM 凭据 | ](/docs/secrets-manager?topic=secrets-manager-iam-credentials) iam_credentials * |
动态 | 动态生成的服务 ID 和 API 密钥,可用于访问需要 IAM 身份验证的 IBM Cloud 服务。 |
键值私钥 | kv |
静态 | 以 JSON 格式构造的敏感数据片段,可用于访问应用程序或资源。 |
SSL/TLS 证书 | imported_cert public_cert \ *private_cert \ * |
静态 |
可用于在服务器和客户机之间建立通信隐私的数字证书类型。 在 Secrets Manager 中,您可以存储以下类型的 certificates.
|
用户凭证 | username_password |
静态 | 可用于登录或访问应用程序或资源的用户名和密码值。 |
服务凭证 | service_credentials |
静态 | 包含服务定义的敏感数据 (例如密钥,证书和 URL) 的 JSON。 |
自定义凭证 | custom_credentials |
静态 | 包含用户定义的敏感数据(如密钥、证书、URL、密码以及由凭证提供者确定的任何类型的任意数据)的 JSON。 |
* 需要 引擎配置,然后才能在服务中创建私钥。
受支持的功能 (按私钥类型)
下表对私钥类型之间的一些公共特征进行了比较和对比。
任意私钥 | IAM 凭证 | 用户凭证 | 键值私钥 | 导入的证书 | 公用证书 | 专用证书 | 服务凭证 | 自定义凭证 | |
---|---|---|---|---|---|---|---|---|---|
自动轮换 | <img src="../icons/checkmark-icon.svg" alt=""复选标记" 图标">[1] | ||||||||
手动旋转 | |||||||||
有效期设置 | |||||||||
通知 | |||||||||
版本历史记录 | |||||||||
复原到先前版本 | |||||||||
SDK 支持 | |||||||||
CLI 插件支持 | |||||||||
HashiCorp Vault API 兼容性 HTTP |
什么秘密
随服务一起存储的私钥由元数据属性和私钥值组成。 虽然元数据属性帮助您识别私钥,但私钥值是受保护服务需要对您或您的应用程序进行认证和授权的数据。
请查看下图以了解如何构造私钥。
{
"name": "my-username-password",
"id": "cb123456-8e73-4857-594839587438",
"description": "Description for this secret",
"secret_type": "username_password",
"secret_group_id": "ab654321-3958-9484-1395840384754",
"state": 1,
"state_description": "Active",
"create_by": "iam-ServiceId-gj403948-3048-6059-304958674930",
"created_at": "2023-03-08-T20:44:11Z",
"labels": [
"dev",
"us-south"
],
"username": "user123",
"password": "cloudy-rainy-coffee-book"
}
-
name
,id
和description
以及其他公共字段保存有关私钥的标识信息。 这些字段存储私钥的常规属性,您可以使用这些属性来了解其用途和历史记录。 -
检索私钥值时,返回的字段将根据私钥类型而有所不同。
以下截断的示例显示了如何表示
arbitrary
私钥的私钥数据。{ "name": "my-secret", "secret_type": "arbitrary", ... "payload": "The quick brown fox jumped over the lazy dog." }
以下截断的示例显示了如何表示
username_password
私钥的私钥数据。{ "name": "my-secret", "secret_type": "username-password", ... "username": "foo", "password": "bar" }
以下截断的示例显示了如何表示
IAM credential
私钥的私钥数据。{ "name": "my-iam-credentials", "secret_type": "iam_credentials", ... "api_key": "RmnPBn6n1dzoo0v3kyznKEpg0WzdTpW9lW7FtKa017_u", "api_key_id": "ApiKey-dcd0b857-b590-4507-8c64-ae89a23e8d76", "service_id": "ServiceId-bb4ccc31-bd31-493a-bb58-52ec399800be", }
以下截断的示例显示了如何表示
KV
私钥的私钥数据。{ "name": "my-kv-secret", "secret_type": "kv", ... "data": '{"key":"value"}' }
以下截断的示例显示了如何表示
imported_cert
和public_cert
私钥的私钥数据。{ "name": "my-certificate", "secret_type": "imported_cert/public_cert", ... "certificate":"...", "intermediate":"...", "private_key":"..." }
以下截断的示例显示了如何表示
private_cert
私钥的私钥数据。{ "name": "my-certificate", "secret_type": "private_cert", ... "certificate":"...", "ca_chain":"...", "private_key":"..." }
以下截断的示例显示了如何表示
service_credentials
私钥的私钥数据。{ "name": "my-secret", "secret_type": "service_credential", ... "credentials": { "key": "The quick brown fox jumped over the lazy dog." } }
以下截断的示例显示了如何表示
custom_credentials
私钥的私钥数据。{ "name": "my-secret", "secret_type": "custom_credential", ... "credentials_content": { "key": "The quick brown fox jumped over the lazy dog." } }
密钥状态和转换
私钥在其生命周期中通过几种状态过渡,这些状态是私钥存在的时间长度以及是否可以访问其关联资源的函数。
Secrets Manager 提供了一个图形用户界面和一个 REST 应用程序接口,用于跟踪秘密在其生命周期中经历的几种状态。 下图显示了一个秘密从产生到销毁的过程中是如何经历各种状态的。
状态 | 描述 |
---|---|
预激活 | 秘密最初是在_预激活状态_下创建的。 处于此状态的私钥将以 预激活 状态显示在 UI 中,以指示它们尚未准备就绪可供使用。 |
活动 |
在私钥可供使用后,它将进入 活动 状态。 私钥将保持活动状态,直到它们到期或被销毁为止。 如果私钥已手动旋转,或者已启用自动旋转,那么以下状态指示符也适用:
|
已停用 | 未创建或处理私钥。 处于此状态的私钥不可恢复,只能从实例中删除。 |
已销毁 |
当与私钥关联的数据到期时,它将进入 已销毁 状态。 处于此状态的私钥不可恢复,只能从实例中删除。 与秘密相关的元数据,如秘密的过渡历史和名称,保存在 Secrets Manager 数据库中。 如果在自动旋转启动后私钥到期,那么以下状态指示符也适用:
|
我该如何开始?
要开始使用私钥,可以转至 Secrets Manager UI 的“私钥”页面,或者查看 API 参考 以了解有关以编程方式创建私钥的更多信息。
-
由于 IAM 凭证是动态私钥,因此自动轮换是内置功能。 当私钥到达其租赁结束时,将自动删除与私钥关联的 API 密钥。 下次读取私钥时,将创建新的 API 密钥。 ↩︎