简体   繁体   English

存储在 Google Secret Manager 中的 DotNet 用户机密

[英]DotNet User secrets stored in Google Secret Manager

I need to deploy a dotnet web app to Google Cloud Run and want to use the user secrets file to store credentials.我需要将 dotnet web 应用程序部署到 Google Cloud Run,并希望使用用户机密文件来存储凭据。 Currently, they are in appsettings which is not secure.目前,它们位于不安全的 appsettings 中。 Has anyone done this using Google Secret Manager?有没有人使用 Google Secret Manager 做到这一点?

  • Is it best to store the key value pairs, a json blob?最好存储键值对,一个 json blob?
  • I would like to pull the values at startup and not during build time.我想在启动时而不是在构建时提取值。

If there are existing examples or snippets they would be appreciated.如果有现有的示例或片段,他们将不胜感激。

Thanks.谢谢。

Google Cloud Run and Google Secret Manager work well together. Google Cloud Run 和 Google Secret Manager 可以很好地协同工作。 The key is to grant privileges to the Cloud Run service account to access Secret Manager.关键是授予 Cloud Run 服务帐户访问 Secret Manager 的权限。 This eliminates needing secrets in your application to access Secret Manager.这消除了在您的应用程序中访问 Secret Manager 的需要。

Access control 访问控制

Is it best to store the key-value pairs, a json blob?最好存储键值对,一个 json blob?

This depends on the amount of data being stored.这取决于存储的数据量。 Normally you create a secret with a name (secretId) and assign data to the secret (via API or the CLI gcloud ).通常,您创建一个具有名称 (secretId) 的密钥并将数据分配给该密钥(通过 API 或 CLI gcloud )。 In your application, you read the secret by name (secretId).在您的应用程序中,您按名称 (secretId) 读取密钥。

I would like to pull the values at startup and not during build time.我想在启动时而不是在构建时提取值。

The link that Seth Vargo (duplicated here) provided has examples in C# and many other languages. Seth Vargo(此处重复)提供的链接有 C# 和许多其他语言的示例。 Your application reads secrets from Secret Manager at run-time.您的应用程序在运行时从 Secret Manager 读取机密。

Creating secrets and versions 创建机密和版本

Guillaume Blaquiere wrote an article showing how to use Secret Manager, Cloud Run and environment variables. Guillaume Blaquiere 写了一篇文章,展示了如何使用 Secret Manager、Cloud Run 和环境变量。 Definitely worth reading.绝对值得一读。

Secret Manager: Improve Cloud Run security without changing the code Secret Manager:在不更改代码的情况下提高 Cloud Run 安全性

IMHO, it is "best" to use a dedicated secret-engine.恕我直言,使用专用的秘密引擎是“最好的”。

Most of the secret engines:大多数秘密引擎:

Hashicorp Vault << probably the most flexible..some call it the "swiss army knife" of secrets Hashicorp Vault << 可能是最灵活的..有人称其为秘密的“瑞士军刀”

Thycotic Secret Store胸腺秘密商店

Azure KeyVault (azure cloud) Azure KeyVault(天蓝色云)

AKS (AWS) (amazon cloud) AKS (AWS)(亚马逊云)

(and your buddy, Google) (和你的朋友,谷歌)

are similar .相似的。

If you are using Kubernetes, you can code up a concrete that will read values from the Kubernetes "mounted secrets".如果您使用的是 Kubernetes,您可以编写一个混凝土,该混凝土将从 Kubernetes“已安装的机密”中读取值。 (I prefer the virtual file mounted secrets). (我更喜欢虚拟文件挂载的秘密)。

What I do is create an abstraction, and then code up a concrete(s) to my implmentation choice.我所做的是创建一个抽象,然后为我的实现选择编写一个具体的代码。

For development environment, you can also code a concrete to this: https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows对于开发环境,您还可以编写具体代码: https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows

But for production, I use the below abstraction, and code up my concrete to one of the solutions above.但是对于生产,我使用下面的抽象,并将我的具体代码编写为上述解决方案之一。

https://pbhadani.com/posts/google-secret-manager/ 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; }
}

Then your IoC registrations will look something like this:然后您的 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>();
        }
        

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM