diff --git a/cmd/image-processing/main.go b/cmd/image-processing/main.go
index 59bee6cbbf..d7f4b1b841 100644
--- a/cmd/image-processing/main.go
+++ b/cmd/image-processing/main.go
@@ -14,6 +14,7 @@ import (
 	"os"
 	"strconv"
 	"strings"
+	"time"
 
 	"github.com/google/go-containerregistry/pkg/name"
 	containerreg "github.com/google/go-containerregistry/pkg/v1"
@@ -40,6 +41,8 @@ type settings struct {
 	label []string
 	insecure bool
 	image,
+	imageTimestamp,
+	imageTimestampFile,
 	resultFileImageDigest,
 	resultFileImageSize,
 	secretPath string
@@ -61,6 +64,10 @@ func initializeFlag() {
 
 	pflag.StringArrayVar(&flagValues.annotation, "annotation", nil, "New annotations to add")
 	pflag.StringArrayVar(&flagValues.label, "label", nil, "New labels to add")
+
+	pflag.StringVar(&flagValues.imageTimestamp, "image-timestamp", "", "number to use as Unix timestamp to set image creation timestamp")
+	pflag.StringVar(&flagValues.imageTimestampFile, "image-timestamp-file", "", "path to a file containing a unix timestamp to set as the image timestamp")
+
 	pflag.StringVar(&flagValues.resultFileImageDigest, "result-file-image-digest", "", "A file to write the image digest to")
 	pflag.StringVar(&flagValues.resultFileImageSize, "result-file-image-size", "", "A file to write the image size to")
 }
@@ -89,6 +96,27 @@ func Execute(ctx context.Context) error {
 		return nil
 	}
 
+	// validate that only one of the image timestamp flags are used
+	if flagValues.imageTimestamp != "" && flagValues.imageTimestampFile != "" {
+		pflag.Usage()
+		return fmt.Errorf("image timestamp and image timestamp file flag is used, they are mutually exclusive, only use one")
+	}
+
+	// validate that image timestamp file exists (if set), and translate it into the imageTimestamp field
+	if flagValues.imageTimestampFile != "" {
+		_, err := os.Stat(flagValues.imageTimestampFile)
+		if err != nil {
+			return fmt.Errorf("image timestamp file flag references a non-existing file: %w", err)
+		}
+
+		data, err := os.ReadFile(flagValues.imageTimestampFile)
+		if err != nil {
+			return fmt.Errorf("failed to read image timestamp from %s: %w", flagValues.imageTimestampFile, err)
+		}
+
+		flagValues.imageTimestamp = string(data)
+	}
+
 	return runImageProcessing(ctx)
 }
 
@@ -151,6 +179,20 @@ func runImageProcessing(ctx context.Context) error {
 		}
 	}
 
+	// mutate the image timestamp
+	if flagValues.imageTimestamp != "" {
+		sec, err := strconv.ParseInt(flagValues.imageTimestamp, 10, 32)
+		if err != nil {
+			return fmt.Errorf("failed to parse image timestamp value %q as a number: %w", flagValues.imageTimestamp, err)
+		}
+
+		log.Println("Mutating the image timestamp")
+		img, imageIndex, err = image.MutateImageOrImageIndexTimestamp(img, imageIndex, time.Unix(sec, 0))
+		if err != nil {
+			return fmt.Errorf("failed to mutate the timestamp: %w", err)
+		}
+	}
+
 	// push the image and determine the digest and size
 	log.Printf("Pushing the image to registry %q\n", imageName.String())
 	digest, size, err := image.PushImageOrImageIndex(imageName, img, imageIndex, options)
@@ -159,6 +201,8 @@ func runImageProcessing(ctx context.Context) error {
 		return err
 	}
 
+	log.Printf("Image %s@%s pushed\n", imageName.String(), digest)
+
 	// Writing image digest to file
 	if digest != "" && flagValues.resultFileImageDigest != "" {
 		if err := os.WriteFile(flagValues.resultFileImageDigest, []byte(digest), 0400); err != nil {
diff --git a/cmd/image-processing/main_suite_test.go b/cmd/image-processing/main_suite_test.go
index 34a97bb535..8f66ab97ba 100644
--- a/cmd/image-processing/main_suite_test.go
+++ b/cmd/image-processing/main_suite_test.go
@@ -9,9 +9,14 @@ import (
 
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
+	"github.com/onsi/gomega/types"
 )
 
 func TestImageProcessingCmd(t *testing.T) {
 	RegisterFailHandler(Fail)
 	RunSpecs(t, "Image Processing Command Suite")
 }
+
+func FailWith(substr string) types.GomegaMatcher {
+	return MatchError(ContainSubstring(substr))
+}
diff --git a/cmd/image-processing/main_test.go b/cmd/image-processing/main_test.go
index 30d7a38b16..ba3de1a056 100644
--- a/cmd/image-processing/main_test.go
+++ b/cmd/image-processing/main_test.go
@@ -12,11 +12,13 @@ import (
 	"net/url"
 	"os"
 	"strconv"
+	"time"
 
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	. "github.com/shipwright-io/build/cmd/image-processing"
 
+	"github.com/google/go-containerregistry/pkg/crane"
 	"github.com/google/go-containerregistry/pkg/name"
 	"github.com/google/go-containerregistry/pkg/registry"
 	containerreg "github.com/google/go-containerregistry/pkg/v1"
@@ -67,6 +69,14 @@ var _ = Describe("Image Processing Resource", func() {
 		f(u.Host)
 	}
 
+	withTempDir := func(f func(target string)) {
+		path, err := os.MkdirTemp(os.TempDir(), "temp-dir")
+		Expect(err).ToNot(HaveOccurred())
+		defer os.RemoveAll(path)
+
+		f(path)
+	}
+
 	withTestImage := func(f func(tag name.Tag)) {
 		withTempRegistry(func(endpoint string) {
 			tag, err := name.NewTag(fmt.Sprintf("%s/%s:%s", endpoint, "temp-image", rand.String(5)))
@@ -77,6 +87,19 @@ var _ = Describe("Image Processing Resource", func() {
 		})
 	}
 
+	withTestImageAsDirectory := func(f func(path string, tag name.Tag)) {
+		withTempRegistry(func(endpoint string) {
+			withTempDir(func(dir string) {
+				tag, err := name.NewTag(fmt.Sprintf("%s/%s:%s", endpoint, "temp-image", rand.String(5)))
+				Expect(err).ToNot(HaveOccurred())
+
+				Expect(crane.SaveOCI(empty.Image, dir)).To(Succeed())
+
+				f(dir, tag)
+			})
+		})
+	}
+
 	getCompressedImageSize := func(img containerreg.Image) int64 {
 		manifest, err := img.Manifest()
 		Expect(err).ToNot(HaveOccurred())
@@ -157,34 +180,70 @@ var _ = Describe("Image Processing Resource", func() {
 		})
 
 		It("should fail in case mandatory arguments are missing", func() {
-			Expect(run()).To(HaveOccurred())
+			Expect(run()).ToNot(Succeed())
 		})
 
 		It("should fail in case --image is empty", func() {
-			Expect(run("--image", "")).To(HaveOccurred())
+			Expect(run(
+				"--image", "",
+			)).To(FailWith("argument must not be empty"))
 		})
 
 		It("should fail in case --image does not exist", func() {
 			Expect(run(
-				"--image", "docker.io/feqlQoDIHc/bcfHFHHXYF",
-			)).To(HaveOccurred())
+				"--image", "docker.io/library/feqlqodihc:bcfhfhhxyf",
+			)).To(FailWith("unexpected status code 401"))
 		})
 
 		It("should fail in case annotation is invalid", func() {
 			withTestImage(func(tag name.Tag) {
 				Expect(run(
+					"--insecure",
 					"--image", tag.String(),
 					"--annotation", "org.opencontainers.image.url*https://my-company.com/images",
-				)).To(HaveOccurred())
+				)).To(FailWith("not enough parts"))
 			})
 		})
 
 		It("should fail in case label is invalid", func() {
 			withTestImage(func(tag name.Tag) {
 				Expect(run(
+					"--insecure",
 					"--image", tag.String(),
 					"--label", " description*image description",
-				)).To(HaveOccurred())
+				)).To(FailWith("not enough parts"))
+			})
+		})
+
+		It("should fail if both --image-timestamp and --image-timestamp-file are used", func() {
+			Expect(run(
+				"--image-timestamp", "1234567890",
+				"--image-timestamp-file", "/tmp/foobar",
+			)).To(FailWith("image timestamp and image timestamp file flag is used"))
+		})
+
+		It("should fail if --image-timestamp-file is used with a non-existing file", func() {
+			Expect("/tmp/does-not-exist").ToNot(BeAnExistingFile())
+			Expect(run(
+				"--image-timestamp-file", "/tmp/does-not-exist",
+			)).To(FailWith("image timestamp file flag references a non-existing file"))
+		})
+
+		It("should fail if --image-timestamp-file referenced file cannot be used", func() {
+			withTempDir(func(wrong string) {
+				Expect(run(
+					"--image-timestamp-file", wrong,
+				)).To(FailWith("failed to read image timestamp from"))
+			})
+		})
+
+		It("should fail in case timestamp is invalid", func() {
+			withTestImage(func(tag name.Tag) {
+				Expect(run(
+					"--insecure",
+					"--image", tag.String(),
+					"--image-timestamp", "foobar",
+				)).To(FailWith("failed to parse image timestamp"))
 			})
 		})
 	})
@@ -266,6 +325,46 @@ var _ = Describe("Image Processing Resource", func() {
 					To(Equal("https://my-company.com/images"))
 			})
 		})
+
+		It("should mutate the image timestamp using a provided timestamp", func() {
+			withTestImageAsDirectory(func(path string, tag name.Tag) {
+				Expect(run(
+					"--insecure",
+					"--push", path,
+					"--image", tag.String(),
+					"--image-timestamp", "1234567890",
+				)).ToNot(HaveOccurred())
+
+				image := getImage(tag)
+
+				cfgFile, err := image.ConfigFile()
+				Expect(err).ToNot(HaveOccurred())
+
+				Expect(cfgFile.Created.Time).To(BeTemporally("==", time.Unix(1234567890, 0)))
+			})
+		})
+
+		It("should mutate the image timestamp using a provided timestamp in a file", func() {
+			withTestImageAsDirectory(func(path string, tag name.Tag) {
+				withTempFile("timestamp", func(filename string) {
+					Expect(os.WriteFile(filename, []byte("1234567890"), os.FileMode(0644)))
+
+					Expect(run(
+						"--insecure",
+						"--push", path,
+						"--image", tag.String(),
+						"--image-timestamp-file", filename,
+					)).ToNot(HaveOccurred())
+
+					image := getImage(tag)
+
+					cfgFile, err := image.ConfigFile()
+					Expect(err).ToNot(HaveOccurred())
+
+					Expect(cfgFile.Created.Time).To(BeTemporally("==", time.Unix(1234567890, 0)))
+				})
+			})
+		})
 	})
 
 	Context("store result after image mutation", func() {