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

✨ Make secret name optional #7358

Open
sagikazarmark opened this issue May 11, 2024 · 9 comments
Open

✨ Make secret name optional #7358

sagikazarmark opened this issue May 11, 2024 · 9 comments
Labels
kind/dx Issue affects the Dagger developer experience: cue syntax, APIs, etc

Comments

@sagikazarmark
Copy link
Contributor

What are you trying to do?

I have a function that creates a secret: https://daggerverse.dev/mod/github.com/sagikazarmark/daggerverse/registry-config@b45dbd7448bb967aca4a538af9ce7f042abf0316#RegistryConfig.secret

The current secret API takes a name at the moment: dag.SetSecret("name", "value").

I'm not sure, but my guess is that name is supposed to be unique (ie. to make sure there is no interference between calls to the same function).

Why is this important to you?

Right now I'm working around the issue mentioned above by exposing an optional secret name argument in the API. I'd rather not do that.

How are you currently working around this?

I'm planning to generate a secret name based on the content: sagikazarmark/daggerverse#104

That will make sure it's unique enough and won't require me to expose options in the API for the secret name.

@shykes shykes added the DX+ label May 14, 2024
@shykes
Copy link
Contributor

shykes commented May 14, 2024

FYI @jedevc @vito @helderco @aluzzardi I think we may need to revisit the design decisions that led to this point. Since then, we launched functions, modules, and didn't revisit the initial plan of adding "secrets providers". Is the current design still relevant? Do we still need the secret name?

@helderco helderco added kind/dx Issue affects the Dagger developer experience: cue syntax, APIs, etc and removed DX+ labels May 14, 2024
@helderco
Copy link
Contributor

helderco commented May 14, 2024

One use case we have today is when adding secrets to a docker build. The secret name will be turned into the secret's id in the Dockerfile:

RUN --mount=type=secret,id=secret-file curl

One problem today is that if you're passing a secret via the CLI, the secret name is an hash. So you currently need to work around that by either creating a new secret inside your function, with the plaintext of the Secret argument and the name that you use in the Dockerfile, or get the secret's name and pass it to the build as a build argument.

Build arg example

Fix for https://github.com/MikaelElkiaer/dagger-examples/blob/ae8a49103ea086f09eb50a423d4bed4871cb0c12/dockerfile-secrets/dagger/main.go:

func (m *DockerfileSecrets) Build(ctx context.Context, buildContext *Directory, secretFile *Secret) (*Container, error) {
	secretName, err := secretFile.Name(ctx)
	if err != nil {
		return nil, err
	}
	return buildContext.
		DockerBuild(dagger.DirectoryDockerBuildOpts{
			BuildArgs: []BuildArg{
				{Name: "SECRET_ID", Value: secretName},
			},
			Secrets: []*Secret{secretFile},
		}), nil
}

In the docker build, you pass the secrets as Secrets: []*Secret{...}. If it were a map, we could use the map’s keys to be the IDs in the Dockerfile. But GraphQL doesn’t support maps so we’d need a new type with name: String! and value: SecretID! fields.

Suggestion: add a withName field

However, since Secret already has a name, I think the simplest solution is adding a withName field to change the secret’s name. So the collapsed example above becomes much simpler:

func (m *DockerfileSecrets) Build(buildContext *Directory, secretFile *Secret) *Container {
	return buildContext.
		DockerBuild(dagger.DirectoryDockerBuildOpts{
			Secrets: []*Secret{secretFile.WithName("secret-file")},
		})
}

If you then make the name in SetSecret optional too (or create a new one without the name), then it won’t bother you if you don’t need to set it, but will also allow to lazily set it when needed.

Not sure about the secret drivers use case as I haven’t thought much about it. Curious to know what @sipsma has to say.

@helderco
Copy link
Contributor

Forgot that we have a dag.Secret("<name>") and that secrets have been isolated in modules:

\cc @jedevc

@jedevc
Copy link
Member

jedevc commented May 16, 2024

Honestly, I'm not opposed to removing dag.Secret. It's incredibly fiddly as an API, and has global state, so would happily see it gone (though it still needs to exist, it could do so just internally).

@shykes
Copy link
Contributor

shykes commented May 22, 2024

2 questions:

  1. What happens if we remove the concept of secret name altogether? It seems like it may be getting in the way and not actually helping

  2. Do we still want a "pluggable secret provider" feature? If so what would that look like? The current design exists in part to keep the door open to such a design in the future. If we no longer feel the need for that, it's important to know. (cc @aluzzardi )

@helderco
Copy link
Contributor

helderco commented May 22, 2024

  1. What happens if we remove the concept of secret name altogether? It seems like it may be getting in the way and not actually helping

How would it work in a docker build as explained in #7358 (comment) ?

Could be an input type like BuildArg:

+ input SecretArg {
+   name: String!
+   value: SecretID!
+ }

 type Container {
   build(
     context: DirectoryID!
     dockerfile: String = "Dockerfile"
     buildArgs: [BuildArg!] = []
-     secrets: [SecretID!] = []
+     secrets: [SecretArg!] = []
     target: String = ""
   ): Container!
 }

This way I'd agree with removing the name as I can't think of anything else where a name is needed.

@helderco
Copy link
Contributor

  1. Do we still want a "pluggable secret provider" feature? If so what would that look like? The current design exists in part to keep the door open to such a design in the future. If we no longer feel the need for that, it's important to know.

I'm struggling to find a need for it when a normal module seems to do the trick.

@shykes
Copy link
Contributor

shykes commented May 22, 2024

@helderco yeah agreed on your idea for solving docker build. If the only reason for keeping a name is docker build... Better to solve the problem for docker build, and remove the secret name.

How does the docker CLI do it? Is it actually a build arg, or a distinct concept of build secret?

@TomChv
Copy link
Member

TomChv commented May 22, 2024

How does the docker CLI do it? Is it actually a build arg, or a distinct concept of build secret?

It's a different concept based on the official doc

RUN --mount=type=secret,id=mytoken
TOKEN=$(cat /run/secrets/mytoken) ...

docker build --secret id=mytoken,src=$HOME/.aws/credentials .

Which has a unique identifier (mytoken in this example).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/dx Issue affects the Dagger developer experience: cue syntax, APIs, etc
Projects
None yet
Development

No branches or pull requests

5 participants