diff --git a/analyzer.go b/analyzer.go index a4630ab5a..607ffa363 100644 --- a/analyzer.go +++ b/analyzer.go @@ -78,7 +78,9 @@ func (f *AnalyzerFactory) NewAnalyzer( } if f.platformAPI.AtLeast("0.7") { - // Temporarily skip ensuring registry access for the analyzer + if err := f.ensureRegistryAccess(additionalTags, cacheImageRef, outputImageRef, runImageRef, previousImageRef); err != nil { + return nil, err + } } else { if err := f.setBuildpacks(analyzer, legacyGroup, legacyGroupPath, logger); err != nil { return nil, err @@ -106,6 +108,30 @@ func (f *AnalyzerFactory) NewAnalyzer( return analyzer, nil } +func (f *AnalyzerFactory) ensureRegistryAccess( + additionalTags []string, + cacheImageRef string, + outputImageRef string, + runImageRef string, + previousImageRef string, +) error { + var readImages, writeImages []string + writeImages = append(writeImages, cacheImageRef) + if f.imageHandler.Kind() == image.RemoteKind { + readImages = append(readImages, previousImageRef, runImageRef) + writeImages = append(writeImages, outputImageRef) + writeImages = append(writeImages, additionalTags...) + } + + if err := f.registryHandler.EnsureReadAccess(readImages...); err != nil { + return errors.Wrap(err, "validating registry read access") + } + if err := f.registryHandler.EnsureWriteAccess(writeImages...); err != nil { + return errors.Wrap(err, "validating registry write access") + } + return nil +} + func (f *AnalyzerFactory) setBuildpacks(analyzer *Analyzer, group buildpack.Group, path string, logger log.Logger) error { if len(group.Group) > 0 { analyzer.Buildpacks = group.Group diff --git a/auth/keychain.go b/auth/keychain.go index 9b2b01c67..2c586542c 100644 --- a/auth/keychain.go +++ b/auth/keychain.go @@ -4,12 +4,9 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io" "os" "regexp" - ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" - "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" "github.com/pkg/errors" @@ -17,11 +14,6 @@ import ( const EnvRegistryAuth = "CNB_REGISTRY_AUTH" -var ( - amazonKeychain = authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard))) - azureKeychain = authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper()) -) - // DefaultKeychain returns a keychain containing authentication configuration for the given images // from the following sources, if they exist, in order of precedence: // the provided environment variable @@ -36,8 +28,6 @@ func DefaultKeychain(images ...string) (authn.Keychain, error) { return authn.NewMultiKeychain( envKeychain, NewResolvedKeychain(authn.DefaultKeychain, images...), - NewResolvedKeychain(amazonKeychain, images...), - NewResolvedKeychain(azureKeychain, images...), ), nil } diff --git a/cmd/lifecycle/analyzer.go b/cmd/lifecycle/analyzer.go index 3a0d901f5..adba0b7ee 100644 --- a/cmd/lifecycle/analyzer.go +++ b/cmd/lifecycle/analyzer.go @@ -10,10 +10,12 @@ import ( "github.com/google/go-containerregistry/pkg/authn" "github.com/buildpacks/lifecycle" + "github.com/buildpacks/lifecycle/auth" "github.com/buildpacks/lifecycle/buildpack" "github.com/buildpacks/lifecycle/cmd" "github.com/buildpacks/lifecycle/cmd/lifecycle/cli" "github.com/buildpacks/lifecycle/platform" + "github.com/buildpacks/lifecycle/priv" ) type analyzeCmd struct { @@ -78,8 +80,23 @@ func (a *analyzeCmd) Args(nargs int, args []string) error { // Privileges validates the needed privileges. func (a *analyzeCmd) Privileges() error { - // Temporarily skip Privileges() call when used inside ACA builder - cmd.DefaultLogger.Debugf("Skipping Privileges() call inside analyzer.") + var err error + a.keychain, err = auth.DefaultKeychain(a.RegistryImages()...) + if err != nil { + return cmd.FailErr(err, "resolve keychain") + } + if a.UseDaemon { + a.docker, err = priv.DockerClient() + if err != nil { + return cmd.FailErr(err, "initialize docker client") + } + } + if err = priv.EnsureOwner(a.UID, a.GID, a.LayersDir, a.CacheDir, a.LaunchCacheDir); err != nil { + return cmd.FailErr(err, "chown volumes") + } + if err = priv.RunAs(a.UID, a.GID); err != nil { + return cmd.FailErr(err, fmt.Sprintf("exec as user %d:%d", a.UID, a.GID)) + } return nil } diff --git a/cmd/lifecycle/detector.go b/cmd/lifecycle/detector.go index 30088e43d..2fdff6528 100644 --- a/cmd/lifecycle/detector.go +++ b/cmd/lifecycle/detector.go @@ -10,6 +10,7 @@ import ( "github.com/buildpacks/lifecycle/internal/encoding" "github.com/buildpacks/lifecycle/platform" "github.com/buildpacks/lifecycle/platform/files" + "github.com/buildpacks/lifecycle/priv" ) type detectCmd struct { @@ -50,8 +51,10 @@ func (d *detectCmd) Args(nargs int, _ []string) error { } func (d *detectCmd) Privileges() error { - // Temporarily skip Privileges() call when used inside ACA builder - cmd.DefaultLogger.Debugf("Skipping Privileges() call inside detector.") + // detector should never be run with privileges + if priv.IsPrivileged() { + return cmd.FailErr(errors.New("refusing to run as root"), "detect") + } return nil } diff --git a/cmd/lifecycle/exporter.go b/cmd/lifecycle/exporter.go index ca2878f74..0c7125a6d 100644 --- a/cmd/lifecycle/exporter.go +++ b/cmd/lifecycle/exporter.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "os" "path/filepath" "strconv" @@ -20,6 +21,7 @@ import ( "github.com/pkg/errors" "github.com/buildpacks/lifecycle" + "github.com/buildpacks/lifecycle/auth" "github.com/buildpacks/lifecycle/buildpack" "github.com/buildpacks/lifecycle/cache" "github.com/buildpacks/lifecycle/cmd" @@ -29,6 +31,7 @@ import ( "github.com/buildpacks/lifecycle/layers" "github.com/buildpacks/lifecycle/platform" "github.com/buildpacks/lifecycle/platform/files" + "github.com/buildpacks/lifecycle/priv" ) type exportCmd struct { @@ -101,8 +104,24 @@ func (e *exportCmd) Args(nargs int, args []string) error { } func (e *exportCmd) Privileges() error { - // Temporarily skip Privileges() call when used inside ACA builder - cmd.DefaultLogger.Debugf("Skipping Privileges() call inside exporter.") + var err error + e.keychain, err = auth.DefaultKeychain(e.registryImages()...) + if err != nil { + return cmd.FailErr(err, "resolve keychain") + } + if e.UseDaemon { + var err error + e.docker, err = priv.DockerClient() + if err != nil { + return cmd.FailErr(err, "initialize docker client") + } + } + if err = priv.EnsureOwner(e.UID, e.GID, e.CacheDir, e.LaunchCacheDir); err != nil { + return cmd.FailErr(err, "chown volumes") + } + if err = priv.RunAs(e.UID, e.GID); err != nil { + return cmd.FailErr(err, fmt.Sprintf("exec as user %d:%d", e.UID, e.GID)) + } return nil } diff --git a/cmd/lifecycle/restorer.go b/cmd/lifecycle/restorer.go index 291992c88..baa8712e2 100644 --- a/cmd/lifecycle/restorer.go +++ b/cmd/lifecycle/restorer.go @@ -14,6 +14,7 @@ import ( "github.com/google/go-containerregistry/pkg/authn" "github.com/buildpacks/lifecycle" + "github.com/buildpacks/lifecycle/auth" "github.com/buildpacks/lifecycle/buildpack" "github.com/buildpacks/lifecycle/cmd" "github.com/buildpacks/lifecycle/cmd/lifecycle/cli" @@ -22,6 +23,7 @@ import ( "github.com/buildpacks/lifecycle/internal/layer" "github.com/buildpacks/lifecycle/platform" "github.com/buildpacks/lifecycle/platform/files" + "github.com/buildpacks/lifecycle/priv" ) const kanikoDir = "/kaniko" @@ -68,8 +70,24 @@ func (r *restoreCmd) Args(nargs int, _ []string) error { } func (r *restoreCmd) Privileges() error { - // Temporarily skip Privileges() call when used inside ACA builder - cmd.DefaultLogger.Debugf("Skipping Privileges() call inside restorer.") + var err error + r.keychain, err = auth.DefaultKeychain(r.RegistryImages()...) + if err != nil { + return cmd.FailErr(err, "resolve keychain") + } + if r.UseDaemon { + var err error + r.docker, err = priv.DockerClient() + if err != nil { + return cmd.FailErr(err, "initialize docker client") + } + } + if err = priv.EnsureOwner(r.UID, r.GID, r.LayersDir, r.CacheDir, r.KanikoDir); err != nil { + return cmd.FailErr(err, "chown volumes") + } + if err = priv.RunAs(r.UID, r.GID); err != nil { + return cmd.FailErr(err, fmt.Sprintf("exec as user %d:%d", r.UID, r.GID)) + } return nil }