Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerfile: Allow mounting secrets directly into env vars #2122

Closed
rittneje opened this issue May 20, 2021 · 14 comments
Closed

Dockerfile: Allow mounting secrets directly into env vars #2122

rittneje opened this issue May 20, 2021 · 14 comments

Comments

@rittneje
Copy link
Contributor

This is a followup to the discussion touched on back in #1703. Currently buildctl supports pulling secrets from env vars via --secret id=xyz,env=ENV_VAR_NAME. However, in order to populate the corresponding env var within RUN, we have to do RUN --mount=type=secret,id=xyz ENV_VAR_NAME="$(cat /run/secrets/xyz)" ....

Not only is having to run cat every time annoyingly repetitive, it doesn't really work well in conjunction with the required=false mount option, since cat will fail due to the file not existing, so even more complex boilerplate is needed.

In addition, if multiple commands need the environment variable, we must explicitly export it, which is a pain because it requires even more boilerplate to be properly safe:

RUN --mount=type=secret,id=pip-index-url \
    PIP_INDEX_URL="$(cat /run/secrets/pip-index-url)" && \
    export PIP_INDEX_URL && \
    pip3 install ...

I propose adding an env option to --mount, which is mutually exclusive with dst. If provided, it contains the name of the environment variable that will be set to the value of the secret in question (and no file will be mounted at /run/secrets). If the mount is not required and the secret does not exist, then the environment variable will not be set at all (rather than having an empty value).

For example:

RUN --mount=type=secret,id=pip-index-url,env=PIP_INDEX_URL pip3 install ...
@tonistiigi
Copy link
Member

tonistiigi commented Jul 7, 2021

I thought this was easy and added to milestone but actually this can't be done in Dockerfile frontend as envs with the secret values would leak to build cache.

So only way to add this is to add a special option to llb.Exec op and it would be a non-backward compatible change.

@rittneje
Copy link
Contributor Author

rittneje commented Jul 7, 2021

@tonistiigi Can you expand upon this? Why is this different with respect to the cache than the existing secret file mounting feature? Or do you mean to say the existing feature leverages a special llb.Exec option?

Also, what is the specific nature of the "non-backward compatible change"? Is it something between buildctl (the command line) and buildkitd (the daemon)? Or something else?

@tonistiigi
Copy link
Member

Yes, secret mount is a special mount type in llb.Exec.

Also, what is the specific nature of the "non-backward compatible change"?

When we can make a change that only touches the frontend it means that older versions of buildkit will still be able to build Dockerfiles with new syntax. With LLB changes Dockerfile will not build unless BuildKit has been updated to support new LLB feature.

@rittneje
Copy link
Contributor Author

rittneje commented Jul 7, 2021

Wouldn't this kind of compatibility issue inevitably arise when trying to use any new kind of mount, not just this change in particular? For example, if --mount=type=ssh didn't exist yet and was to be introduced in v0.9.0, anyone who tried to build such a Dockerfile with an earlier version of BuildKit would encounter a failure (since llb.AddSSHSocket would not exist).

By the way, if it would make things simpler in the implementation, I personally would be fine having this new feature be something like --mount=type=secretenv, if only to avoid confusion over which options (such as uid and gid) can be meaningfully specified. Not that that helps at all with the compatibility issue.

@tonistiigi
Copy link
Member

Wouldn't this kind of compatibility issue inevitably arise when trying to use any new kind of mount,

Yes, I'm not saying that we can never add this. Just that it is more complicated than what I initially assumed.

@cep21
Copy link

cep21 commented Dec 21, 2021

Another example is Go's GOPROXY variable, which when used via CI/CD from github/circleci/etc generally includes auth credentials, so needs to be a secret in the build.

@tonistiigi
Copy link
Member

LLB side of this is implemented in #2579

@kevcube
Copy link

kevcube commented Apr 29, 2022

@rittneje

... since cat will fail due to the file not existing, so even more complex boilerplate is needed.

Can you share this boilerplate please?

@rittneje
Copy link
Contributor Author

@kevcube It's in the example I shared.

RUN --mount=type=secret,id=pip-index-url \
    PIP_INDEX_URL="$(cat /run/secrets/pip-index-url)" && \
    export PIP_INDEX_URL && \
    pip3 install ...

@tonistiigi tonistiigi changed the title Allow mounting secrets directly into env vars Dockerfile: Allow mounting secrets directly into env vars May 13, 2022
@rittneje
Copy link
Contributor Author

@tonistiigi What still needs to be done for this feature to be fully realized?

@rittneje
Copy link
Contributor Author

ping @tonistiigi

@tonistiigi
Copy link
Member

What still needs to be done for this feature to be fully realized?

Dockerfile frontend would need to be able to parse it from the flag and do the correct LLB calls. For testing all this can be done with an external frontend image.

@rittneje
Copy link
Contributor Author

rittneje commented Aug 7, 2023

@tonistiigi any update on this?

a-palchikov added a commit to a-palchikov/buildkit that referenced this issue Aug 5, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.
a-palchikov added a commit to a-palchikov/buildkit that referenced this issue Aug 6, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.

Signed-off-by: a-palchikov <[email protected]>
a-palchikov added a commit to a-palchikov/buildkit that referenced this issue Aug 8, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.

Signed-off-by: a-palchikov <[email protected]>
a-palchikov added a commit to a-palchikov/buildkit that referenced this issue Aug 9, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.

Signed-off-by: a-palchikov <[email protected]>
a-palchikov added a commit to a-palchikov/buildkit that referenced this issue Aug 12, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.

Signed-off-by: a-palchikov <[email protected]>
a-palchikov added a commit to a-palchikov/buildkit that referenced this issue Aug 13, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.

Signed-off-by: a-palchikov <[email protected]>
a-palchikov added a commit to a-palchikov/buildkit that referenced this issue Aug 19, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.

Signed-off-by: a-palchikov <[email protected]>
a-palchikov added a commit to a-palchikov/buildkit that referenced this issue Aug 19, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.

Signed-off-by: a-palchikov <[email protected]>
@a-palchikov
Copy link
Contributor

@rittneje The change implementing support for this has been merged.

daghack pushed a commit to daghack/buildkit that referenced this issue Sep 19, 2024
This adds the syntax to Dockerfile frontend.
I purposedly chose to use a simple format for this as it's likely going
to be debated. As implemented, the following format is supported:

```
RUN --mount=type=secret,id=MYSECRET,env
```
or, more explicitly:

```
RUN --mount=type=secret,id=MYSECRET,env=true
```

will mount the secret with id MYSECRET as a new environment variable with the same name.

Using 'target', it's possible to create a different environment
variable:
```
RUN --mount=type=secret,id=mysecret,target=MY_SECRET,env
```
will mount 'mysecret' secret as MY_SECRET environment variable.

Any suggestions on making it more ergonomic are welcome.

Signed-off-by: a-palchikov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants