buildkit secrets support
- Secrets are never exposed in plaintext in the Cue tree. `dagger query` won't dump secrets anymore, Cue errors won't contain them either. - BuildKit-native secrets support through a new `mount` type. This ensures secrets will never be part of containerd layers, buildkit cache and generally speaking will never be saved to disk in plaintext. - Updated netlify as an example - Added tests - Changed the Cue definition of a secret to: ``` @dagger(secret) id: string } ``` This is to ensure both that setting the wrong input type on a secret (e.g. `dagger input text`) will fail, and attempting to misuse the secret (e.g. interpolating, passing as an env variable, etc) will also fail properly. Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
47
solver/secretsprovider.go
Normal file
47
solver/secretsprovider.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package solver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/session/secrets"
|
||||
"github.com/moby/buildkit/session/secrets/secretsprovider"
|
||||
"github.com/rs/zerolog/log"
|
||||
"go.dagger.io/dagger/state"
|
||||
)
|
||||
|
||||
func NewSecretsProvider(st *state.State) session.Attachable {
|
||||
return secretsprovider.NewSecretProvider(&inputStore{st})
|
||||
}
|
||||
|
||||
type inputStore struct {
|
||||
st *state.State
|
||||
}
|
||||
|
||||
func (s *inputStore) GetSecret(ctx context.Context, id string) ([]byte, error) {
|
||||
lg := log.Ctx(ctx)
|
||||
|
||||
const secretPrefix = "secret="
|
||||
|
||||
if !strings.HasPrefix(id, secretPrefix) {
|
||||
return nil, secrets.ErrNotFound
|
||||
}
|
||||
|
||||
id = strings.TrimPrefix(id, secretPrefix)
|
||||
|
||||
input, ok := s.st.Inputs[id]
|
||||
if !ok {
|
||||
return nil, secrets.ErrNotFound
|
||||
}
|
||||
if input.Secret == nil {
|
||||
return nil, secrets.ErrNotFound
|
||||
}
|
||||
|
||||
lg.
|
||||
Debug().
|
||||
Str("id", id).
|
||||
Msg("injecting secret")
|
||||
|
||||
return []byte(input.Secret.PlainText()), nil
|
||||
}
|
@@ -3,7 +3,9 @@ package solver
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
bk "github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/client/llb"
|
||||
@@ -25,6 +27,7 @@ type Opts struct {
|
||||
Gateway bkgw.Client
|
||||
Events chan *bk.SolveStatus
|
||||
Auth *RegistryAuthProvider
|
||||
Secrets session.Attachable
|
||||
NoCache bool
|
||||
}
|
||||
|
||||
@@ -100,7 +103,11 @@ func (s Solver) ResolveImageConfig(ctx context.Context, ref string, opts llb.Res
|
||||
|
||||
// Solve will block until the state is solved and returns a Reference.
|
||||
func (s Solver) SolveRequest(ctx context.Context, req bkgw.SolveRequest) (*bkgw.Result, error) {
|
||||
return s.opts.Gateway.Solve(ctx, req)
|
||||
res, err := s.opts.Gateway.Solve(ctx, req)
|
||||
if err != nil {
|
||||
return nil, CleanError(err)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Solve will block until the state is solved and returns a Reference.
|
||||
@@ -150,7 +157,7 @@ func (s Solver) Export(ctx context.Context, st llb.State, img *dockerfile2llb.Im
|
||||
|
||||
opts := bk.SolveOpt{
|
||||
Exports: []bk.ExportEntry{output},
|
||||
Session: []session.Attachable{s.opts.Auth},
|
||||
Session: []session.Attachable{s.opts.Auth, s.opts.Secrets},
|
||||
}
|
||||
|
||||
ch := make(chan *bk.SolveStatus)
|
||||
@@ -204,3 +211,22 @@ func dumpLLB(def *bkpb.Definition) ([]byte, error) {
|
||||
}
|
||||
return json.Marshal(ops)
|
||||
}
|
||||
|
||||
// A helper to remove noise from buildkit error messages.
|
||||
// FIXME: Obviously a cleaner solution would be nice.
|
||||
func CleanError(err error) error {
|
||||
noise := []string{
|
||||
"executor failed running ",
|
||||
"buildkit-runc did not terminate successfully",
|
||||
"rpc error: code = Unknown desc = ",
|
||||
"failed to solve: ",
|
||||
}
|
||||
|
||||
msg := err.Error()
|
||||
|
||||
for _, s := range noise {
|
||||
msg = strings.ReplaceAll(msg, s, "")
|
||||
}
|
||||
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
Reference in New Issue
Block a user