在Golang中使用Docker将敏感数据作为参数传递

huangapple go评论81阅读模式
英文:

Pass sensitive data as argument using docker in Golang

问题

我已经用Go创建了一个程序,它接收两个参数,project_idprivate_token。基本上,我是这样做的:

project_id := flag.String("project", "", "项目的ID")
private_token := flag.String("pat", "", "具有API和读取用户权限的个人访问令牌")
flag.Parse()

我创建了以下的Docker镜像:

FROM golang:1.16-alpine

WORKDIR /app

COPY . /app

RUN go build

ENV PROJECT=""
ENV PRIVATE_TOKEN=""

ENTRYPOINT "./my-program" "-project" $PROJECT "-pat" $PRIVATE_TOKEN

我通过以下命令运行镜像:

docker run -e PROJECT=29065042 -e PRIVATE_TOKEN="glpat-1CHf9T8Nz98W8ZzyT7V4" --rm -it my-image-name

如你所见,我传递了一个私有令牌,这是敏感数据。我想知道这是否是从Docker传递敏感数据给我的Go程序的最佳方法,或者是否有更好的模式?

英文:

I have created a program in Go which receives to arguments, project_id and private_token. Basically that is how I do it:

project_id := flag.String("project", "", "The id of the project")
private_token := flag.String("pat", "", "The personal access token with api and read user permissions")
flag.Parse()

I have created the following docker image:

FROM golang:1.16-alpine

WORKDIR /app

COPY . /app

RUN go build

ENV PROJECT=""
ENV PRIVATE_TOKEN=""

ENTRYPOINT "./my-program" "-project" $PROJECT "-pat" $PRIVATE_TOKEN

I run the image by running:

docker run -e PROJECT=29065042 -e PRIVATE_TOKEN="glpat-1CHf9T8Nz98W8ZzyT7V4" --rm -it my-image-name

As you can see, I'm passing a private token, which is a sensitive data. I wanted to know if this is the best approach of passing sensitive data from docker to my go program or if there is a better pattern?

答案1

得分: 2

在使用Docker的Go应用程序中,有不同的方法来存储和使用敏感数据。每种方法都有其优缺点。

  1. 在代码中硬编码密钥(绝对不要这样做):
const (
    PROJECT_NAME = "MyProject"
    PRIVATE_TOKEN = "kjdnioqvnocw"
)

优点:无。绝对不要这样做。
缺点:开发人员会在日常工作中看到您的生产密钥。您的密钥将被提交到源代码控制中,这都是安全风险。此外,您需要修改代码以在不同的环境(如开发、测试和生产)中使用它。

  1. 将密钥放入环境变量中,从.env文件中加载:
    有两个包可以方便地使用.env文件,godotenvviper,我更喜欢使用godotenv,因为它更简单。
    优点:开发人员看不到您的生产密钥。您可以在开发、测试和生产中使用不同的密钥,而无需修改代码。
    缺点:恶意代码可能会读取您的密钥。您的应用程序的大部分代码可能是开源库。糟糕的代码可能会悄悄混入而您并不知情。

  2. 将密钥放入专用的密钥管理器中,如HashiCorp的VaultGoogle Cloud的Secret ManagerAWS的Parameter StoreAzure的Key Vault
    优点:恶意代码更难读取您的密钥。您可以获得谁在何时访问密钥的审计记录。您可以为更新密钥和读取密钥的人员分配细粒度角色。您可以更新和版本化您的密钥。
    缺点:这是您需要学习的额外技术。除非它包含在您使用的云平台中,否则它可能是需要设置和管理的额外软件。

因此,选择实际上是在上述第2和第3项之间。您的选择将取决于您的密钥有多敏感以及使用专用密钥管理器是否需要额外的工作。例如,如果您的项目在Google Cloud Platform上运行,那么Secret Manager只需一个API调用即可。在其他主要云平台上可能也同样简单,但我没有亲身经验。

英文:

There are different ways to store and use sensitive data inside your Go application with docker. Every method has its pros and cons.

1. Hard-code the secrets inside the code.(never do this)

const (
    PROJECT_NAME = "MyProject"
    PRIVATE_TOKEN="kjdnioqvnocw"

)

  • Pros: None. Never do this.
  • Cons: Developers will see your production secrets as part of their regular work. Your secrets will be checked into source control. Both are security risks. Also, you have to modify the code to use it in different environments, like dev, test, and production.<br>

2. Put secrets in environment variables, loaded from a .env file.
There is two package to use .env file easily , godotenv and viper , I prefer godotenv beacuse it's much easier .<br>

  • Pros: Developers won't see your production secrets. You can use different secrets in dev, test, and production, without having to modify the code.
  • Cons: Malicious code can read your secrets. The bulk of your application's code is probably open-source libraries. Bad code may creep in without you knowing it.

3. Put secrets in a dedicated secret manager, like Vault by HashiCorp , Secret Manager by Google Cloud. Parameter Store by AWS , Azure Key Vault from Azure

  • Pros: It's harder for malicious code to read your secrets. You get auditing of who accessed secrets when. You can assign fine-grained roles for who updates secrets and who can read them. You can update and version your secrets.
  • Cons: It's additional technology that you have learn. It may be an additional piece of software that you need to set up and manage, unless it's included in the cloud platform you're using.

So the choice is really between items 2 and 3 above. Which one you pick will depend on how sensitive your secrets are and how much extra work it would be to use a dedicated secret manager. For example, if your project is running on Google Cloud Platform, the Secret Manager is just one API call away. It may be just as easy on the other major cloud platforms, but I don't have first-hand experience with them.

答案2

得分: 1

ENTRYPOINT "./my-program" "-project" $PROJECT "-pat" $PRIVATE_TOKEN 是一个独立的 shell,无法共享前面 Dockerfile 行的变量,这是使用 Dockerfile 的一个权衡。

我建议修改 ./my-program,使其像 kubectl 一样读取一个 config-file。有一个很好的 Viper 包可以帮助实现这种方法。

例如:
ENTRYPOINT "./my-program" "--config-file" "config.yaml"

在 ENTRYPOINT 之前,你应该将所有的密钥保存在 config.yaml 中。

参考资料:https://github.com/spf13/viper

英文:

ENTRYPOINT &quot;./my-program&quot; &quot;-project&quot; $PROJECT &quot;-pat&quot; $PRIVATE_TOKEN is an independent shell and cannot share variables from previous Dokerfile lines, this is a tradeoff of using Dockerfiles.

I would like to suggest to modify ./my-program to read a config-file like kubectl does. There is a good Viper package that helps to achieve this approach.

ie:
ENTRYPOINT &quot;./my-program&quot; &quot;--config-file&quot; &quot;config.yaml&quot;

You should save all the secrets in the config.yaml before ENTRYPOINT

References: https://github.com/spf13/viper

huangapple
  • 本文由 发表于 2022年7月8日 04:16:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/72903738.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定