Handle secrets in DockerLogin operation

Before, secret was a plain text string, but it could lead to security issue
so we are now handling secrets as `dagger.#Secret` or string.
I've add a new struct SecretStore that expose the inputStore to easily
retrieve secret value.

Signed-off-by: Tom Chauveau <tom.chauveau@epitech.eu>
This commit is contained in:
Tom Chauveau 2021-08-31 13:04:16 +02:00
parent 47ef0a4c2a
commit a9fd97d7fe
No known key found for this signature in database
GPG Key ID: 3C9847D981AAC1BF
5 changed files with 55 additions and 22 deletions

View File

@ -128,15 +128,15 @@ func (c *Client) buildfn(ctx context.Context, st *state.State, env *environment.
// buildkit auth provider (registry) // buildkit auth provider (registry)
auth := solver.NewRegistryAuthProvider() auth := solver.NewRegistryAuthProvider()
// secrets // session (secrets & store)
secrets := solver.NewSecretsProvider(st) secretsStore := solver.NewSecretsStoreProvider(st)
// Setup solve options // Setup solve options
opts := bk.SolveOpt{ opts := bk.SolveOpt{
LocalDirs: localdirs, LocalDirs: localdirs,
Session: []session.Attachable{ Session: []session.Attachable{
auth, auth,
secrets, secretsStore.Secrets,
solver.NewDockerSocketProvider(), solver.NewDockerSocketProvider(),
}, },
CacheExports: c.cfg.CacheExports, CacheExports: c.cfg.CacheExports,
@ -171,12 +171,12 @@ func (c *Client) buildfn(ctx context.Context, st *state.State, env *environment.
resp, err := c.c.Build(ctx, opts, "", func(ctx context.Context, gw bkgw.Client) (*bkgw.Result, error) { resp, err := c.c.Build(ctx, opts, "", func(ctx context.Context, gw bkgw.Client) (*bkgw.Result, error) {
s := solver.New(solver.Opts{ s := solver.New(solver.Opts{
Control: c.c, Control: c.c,
Gateway: gw, Gateway: gw,
Events: eventsCh, Events: eventsCh,
Auth: auth, Auth: auth,
Secrets: secrets, SecretsStore: secretsStore,
NoCache: c.cfg.NoCache, NoCache: c.cfg.NoCache,
}) })
// Close events channel // Close events channel

View File

@ -651,9 +651,27 @@ func (p *Pipeline) DockerLogin(ctx context.Context, op *compiler.Value, st llb.S
return st, err return st, err
} }
secret, err := op.Lookup("secret").String() // Inject secret as plain text or retrieve string
// FIXME If we could create secret directly in `cue`, we could clean up
// that condition
// But currently it's not possible because ECR secret's is a string
// so we need to handle both option (string & secrets)
secretValue, err := op.Lookup("secret").String()
if err != nil { if err != nil {
return st, err // Retrieve secret
if secret := op.Lookup("secret"); secret.Exists() {
id, err := getSecretID(secret)
if err != nil {
return st, err
}
secretBytes, err := p.s.GetOptions().SecretsStore.Store.GetSecret(ctx, id)
if err != nil {
return st, err
}
secretValue = string(secretBytes)
} else {
return st, err
}
} }
target, err := op.Lookup("target").String() target, err := op.Lookup("target").String()
@ -661,7 +679,7 @@ func (p *Pipeline) DockerLogin(ctx context.Context, op *compiler.Value, st llb.S
return st, err return st, err
} }
p.s.AddCredentials(target, username, secret) p.s.AddCredentials(target, username, secretValue)
log. log.
Ctx(ctx). Ctx(ctx).
Debug(). Debug().

View File

@ -11,8 +11,19 @@ import (
"go.dagger.io/dagger/state" "go.dagger.io/dagger/state"
) )
func NewSecretsProvider(st *state.State) session.Attachable { type SecretsStore struct {
return secretsprovider.NewSecretProvider(&inputStore{st}) Secrets session.Attachable
Store *inputStore
}
func NewSecretsStoreProvider(st *state.State) SecretsStore {
store := &inputStore{st}
return SecretsStore{
Secrets: secretsprovider.NewSecretProvider(store),
Store: store,
}
} }
type inputStore struct { type inputStore struct {

View File

@ -26,12 +26,12 @@ type Solver struct {
} }
type Opts struct { type Opts struct {
Control *bk.Client Control *bk.Client
Gateway bkgw.Client Gateway bkgw.Client
Events chan *bk.SolveStatus Events chan *bk.SolveStatus
Auth *RegistryAuthProvider Auth *RegistryAuthProvider
Secrets session.Attachable SecretsStore SecretsStore
NoCache bool NoCache bool
} }
func New(opts Opts) Solver { func New(opts Opts) Solver {
@ -61,6 +61,10 @@ func invalidateCache(def *llb.Definition) error {
return nil return nil
} }
func (s Solver) GetOptions() Opts {
return s.opts
}
func (s Solver) NoCache() bool { func (s Solver) NoCache() bool {
return s.opts.NoCache return s.opts.NoCache
} }
@ -189,7 +193,7 @@ func (s Solver) Export(ctx context.Context, st llb.State, img *dockerfile2llb.Im
Exports: []bk.ExportEntry{output}, Exports: []bk.ExportEntry{output},
Session: []session.Attachable{ Session: []session.Attachable{
s.opts.Auth, s.opts.Auth,
s.opts.Secrets, s.opts.SecretsStore.Secrets,
NewDockerSocketProvider(), NewDockerSocketProvider(),
}, },
} }

View File

@ -68,7 +68,7 @@ package op
target: string target: string
username: string username: string
// FIXME: should be a #Secret (circular import) // FIXME: should be a #Secret (circular import)
secret: string | bytes secret: _ @dagger(secret)
} }
#FetchContainer: { #FetchContainer: {