存储在 Google 秘密管理器中的 DotNet 用户秘密
DotNet User secrets stored in Google Secret Manager
我需要将 dotnet web 应用程序部署到 Google 云 运行 并希望使用用户机密文件来存储凭据。目前,它们位于不安全的应用程序设置中。有人使用 Google Secret Manager 做过吗?
- 最好存储键值对,json blob 吗?
- 我想在启动时而不是在构建期间提取值。
如果有现成的示例或片段,我们将不胜感激。
谢谢。
恕我直言,使用专用的秘密引擎是“最好的”。
大多数秘密引擎:
Hashicorp Vault << 可能是最灵活的..有人称它为秘密的“瑞士军刀”
Thycotic 秘密商店
Azure KeyVault(蔚蓝云)
AKS (AWS)(亚马逊云)
(还有你的好友,Google)
相似。
如果您使用的是 Kubernetes,则可以编写一个具体的代码来从 Kubernetes“安装的秘密”中读取值。 (我更喜欢虚拟文件挂载的秘密)。
我所做的是创建一个抽象,然后根据我的实现选择编写一个或多个具体代码。
对于开发环境,你也可以编写一个具体的代码:https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows
但是对于生产,我使用下面的抽象,并将我的具体代码编码为上面的解决方案之一。
https://pbhadani.com/posts/google-secret-manager/
using System.Threading;
using System.Threading.Tasks;
public interface ISecretRetriever
{
Task<SecretModel> GetSecret(string secretName);
Task<SecretModel> GetSecret(string secretName, CancellationToken ct);
}
..
using System.Collections.Generic;
using System.Linq;
[System.Diagnostics.DebuggerDisplay("SecretName='{SecretName}', SubSecretsCount='{SubSecrets.Count}'")]
public class SecretModel
{
public SecretModel()
{
this.SubSecrets = new List<SubSecret>();
}
public string SecretName { get; set; }
public ICollection<SubSecret> SubSecrets { get; set; }
}
..
using System.Security;
[System.Diagnostics.DebuggerDisplay("KeyName = '{KeyName}', SecretValueLength='{null == SecretValue ? 0 : SecretValue.Length}'")]
public class SubSecret
{
public string KeyName { get; set; }
public SecureString SecretValue { get; set; }
}
那么您的 IoC 注册将如下所示:
if (hostingEnvironment.IsDevelopment()) /* https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.hostingenvironmentextensions.isdevelopment?view=aspnetcore-3.1 */
{
/* code your LowerEnvironmentsInsecureSecretRetriever to https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows */
services.AddSingleton<ISecretRetriever, LowerEnvironmentsInsecureSecretRetriever>();
}
else
{
/* code your HashicorpVaultSecretRetriever to HashicorpVault (or use a different one */
services.AddSingleton<ISecretRetriever, HashicorpVaultSecretRetriever>();
}
Google Cloud 运行 和 Google Secret Manager 协同工作。关键是授予 Cloud 运行 服务帐户访问 Secret Manager 的权限。这消除了在您的应用程序中访问秘密管理器所需的秘密。
Is it best to store the key-value pairs, a json blob?
这取决于存储的数据量。通常,您使用名称 (secretId) 创建一个秘密并将数据分配给该秘密(通过 API 或 CLI gcloud
)。在您的应用程序中,您按名称 (secretId) 读取机密。
I would like to pull the values at startup and not during build time.
Seth Vargo(此处复制)提供的 link 包含 C# 和许多其他语言的示例。您的应用程序在 运行 次从 Secret Manager 读取机密。
Guillaume Blaquiere 撰写了一篇文章,展示了如何使用 Secret Manager、Cloud 运行 和环境变量。绝对值得一读。
Secret Manager: Improve Cloud Run security without changing the code
我需要将 dotnet web 应用程序部署到 Google 云 运行 并希望使用用户机密文件来存储凭据。目前,它们位于不安全的应用程序设置中。有人使用 Google Secret Manager 做过吗?
- 最好存储键值对,json blob 吗?
- 我想在启动时而不是在构建期间提取值。
如果有现成的示例或片段,我们将不胜感激。
谢谢。
恕我直言,使用专用的秘密引擎是“最好的”。
大多数秘密引擎:
Hashicorp Vault << 可能是最灵活的..有人称它为秘密的“瑞士军刀”
Thycotic 秘密商店
Azure KeyVault(蔚蓝云)
AKS (AWS)(亚马逊云)
(还有你的好友,Google)
相似。
如果您使用的是 Kubernetes,则可以编写一个具体的代码来从 Kubernetes“安装的秘密”中读取值。 (我更喜欢虚拟文件挂载的秘密)。
我所做的是创建一个抽象,然后根据我的实现选择编写一个或多个具体代码。
对于开发环境,你也可以编写一个具体的代码:https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows
但是对于生产,我使用下面的抽象,并将我的具体代码编码为上面的解决方案之一。
https://pbhadani.com/posts/google-secret-manager/
using System.Threading;
using System.Threading.Tasks;
public interface ISecretRetriever
{
Task<SecretModel> GetSecret(string secretName);
Task<SecretModel> GetSecret(string secretName, CancellationToken ct);
}
..
using System.Collections.Generic;
using System.Linq;
[System.Diagnostics.DebuggerDisplay("SecretName='{SecretName}', SubSecretsCount='{SubSecrets.Count}'")]
public class SecretModel
{
public SecretModel()
{
this.SubSecrets = new List<SubSecret>();
}
public string SecretName { get; set; }
public ICollection<SubSecret> SubSecrets { get; set; }
}
..
using System.Security;
[System.Diagnostics.DebuggerDisplay("KeyName = '{KeyName}', SecretValueLength='{null == SecretValue ? 0 : SecretValue.Length}'")]
public class SubSecret
{
public string KeyName { get; set; }
public SecureString SecretValue { get; set; }
}
那么您的 IoC 注册将如下所示:
if (hostingEnvironment.IsDevelopment()) /* https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.hostingenvironmentextensions.isdevelopment?view=aspnetcore-3.1 */
{
/* code your LowerEnvironmentsInsecureSecretRetriever to https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows */
services.AddSingleton<ISecretRetriever, LowerEnvironmentsInsecureSecretRetriever>();
}
else
{
/* code your HashicorpVaultSecretRetriever to HashicorpVault (or use a different one */
services.AddSingleton<ISecretRetriever, HashicorpVaultSecretRetriever>();
}
Google Cloud 运行 和 Google Secret Manager 协同工作。关键是授予 Cloud 运行 服务帐户访问 Secret Manager 的权限。这消除了在您的应用程序中访问秘密管理器所需的秘密。
Is it best to store the key-value pairs, a json blob?
这取决于存储的数据量。通常,您使用名称 (secretId) 创建一个秘密并将数据分配给该秘密(通过 API 或 CLI gcloud
)。在您的应用程序中,您按名称 (secretId) 读取机密。
I would like to pull the values at startup and not during build time.
Seth Vargo(此处复制)提供的 link 包含 C# 和许多其他语言的示例。您的应用程序在 运行 次从 Secret Manager 读取机密。
Guillaume Blaquiere 撰写了一篇文章,展示了如何使用 Secret Manager、Cloud 运行 和环境变量。绝对值得一读。
Secret Manager: Improve Cloud Run security without changing the code