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)
auth := solver.NewRegistryAuthProvider()
// secrets
secrets := solver.NewSecretsProvider(st)
// session (secrets & store)
secretsStore := solver.NewSecretsStoreProvider(st)
// Setup solve options
opts := bk.SolveOpt{
LocalDirs: localdirs,
Session: []session.Attachable{
auth,
secrets,
secretsStore.Secrets,
solver.NewDockerSocketProvider(),
},
CacheExports: c.cfg.CacheExports,
@ -175,7 +175,7 @@ func (c *Client) buildfn(ctx context.Context, st *state.State, env *environment.
Gateway: gw,
Events: eventsCh,
Auth: auth,
Secrets: secrets,
SecretsStore: secretsStore,
NoCache: c.cfg.NoCache,
})

View File

@ -651,17 +651,35 @@ func (p *Pipeline) DockerLogin(ctx context.Context, op *compiler.Value, st llb.S
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 {
// 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()
if err != nil {
return st, err
}
p.s.AddCredentials(target, username, secret)
p.s.AddCredentials(target, username, secretValue)
log.
Ctx(ctx).
Debug().

View File

@ -11,8 +11,19 @@ import (
"go.dagger.io/dagger/state"
)
func NewSecretsProvider(st *state.State) session.Attachable {
return secretsprovider.NewSecretProvider(&inputStore{st})
type SecretsStore struct {
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 {

View File

@ -30,7 +30,7 @@ type Opts struct {
Gateway bkgw.Client
Events chan *bk.SolveStatus
Auth *RegistryAuthProvider
Secrets session.Attachable
SecretsStore SecretsStore
NoCache bool
}
@ -61,6 +61,10 @@ func invalidateCache(def *llb.Definition) error {
return nil
}
func (s Solver) GetOptions() Opts {
return s.opts
}
func (s Solver) NoCache() bool {
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},
Session: []session.Attachable{
s.opts.Auth,
s.opts.Secrets,
s.opts.SecretsStore.Secrets,
NewDockerSocketProvider(),
},
}

View File

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