diff --git a/cmd/flux/bootstrap.go b/cmd/flux/bootstrap.go
index 2abfc9ff79abd602c326b841e59a42f3b608c9cc..5b0eb40592a64e0399d0ff06825d997e15aa4a5a 100644
--- a/cmd/flux/bootstrap.go
+++ b/cmd/flux/bootstrap.go
@@ -68,9 +68,9 @@ type bootstrapFlags struct {
 	authorName  string
 	authorEmail string
 
-	gpgKeyPath    string
-	gpgPassphrase string
-	gpgKeyID      string
+	gpgKeyRingPath string
+	gpgPassphrase  string
+	gpgKeyID       string
 
 	commitMessageAppendix string
 }
@@ -123,8 +123,8 @@ func init() {
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.authorName, "author-name", "Flux", "author name for Git commits")
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.authorEmail, "author-email", "", "author email for Git commits")
 
-	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.gpgKeyPath, "gpg-key", "", "path to secret gpg key for signing commits")
-	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.gpgPassphrase, "gpg-passphrase", "", "passphrase for decrypting secret gpg key")
+	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.gpgKeyRingPath, "gpg-key-ring", "", "path to GPG key ring for signing commits")
+	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.gpgPassphrase, "gpg-passphrase", "", "passphrase for decrypting GPG private key")
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.gpgKeyID, "gpg-key-id", "", "key id for selecting a particular key")
 
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.commitMessageAppendix, "commit-message-appendix", "", "string to add to the commit messages, e.g. '[ci skip]'")
diff --git a/cmd/flux/bootstrap_git.go b/cmd/flux/bootstrap_git.go
index 894742c4d31520106e0505f480975f5baca24349..786a2692aa047aa9f2842f805e2f10e226142f57 100644
--- a/cmd/flux/bootstrap_git.go
+++ b/cmd/flux/bootstrap_git.go
@@ -224,7 +224,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
 		bootstrap.WithPostGenerateSecretFunc(promptPublicKey),
 		bootstrap.WithLogger(logger),
 		bootstrap.WithCABundle(caBundle),
-		bootstrap.WithGitCommitSigning(bootstrapArgs.gpgKeyPath, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
+		bootstrap.WithGitCommitSigning(bootstrapArgs.gpgKeyRingPath, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
 	}
 
 	// Setup bootstrapper with constructed configs
diff --git a/internal/bootstrap/bootstrap_plain_git.go b/internal/bootstrap/bootstrap_plain_git.go
index 898f976dcbe0d3f6f2a428ed1adf5bf1039cf848..f7c25fe0942cfe8e449c448612e4d9d95280556c 100644
--- a/internal/bootstrap/bootstrap_plain_git.go
+++ b/internal/bootstrap/bootstrap_plain_git.go
@@ -53,9 +53,9 @@ type PlainGitBootstrapper struct {
 	author                git.Author
 	commitMessageAppendix string
 
-	gpgKeyPath    string
-	gpgPassphrase string
-	gpgKeyID      string
+	gpgKeyRingPath string
+	gpgPassphrase  string
+	gpgKeyID       string
 
 	kubeconfig  string
 	kubecontext string
@@ -146,7 +146,7 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest
 	}
 
 	// Git commit generated
-	gpgOpts := git.WithGpgSigningOption(b.gpgKeyPath, b.gpgPassphrase, b.gpgKeyID)
+	gpgOpts := git.WithGpgSigningOption(b.gpgKeyRingPath, b.gpgPassphrase, b.gpgKeyID)
 	commitMsg := fmt.Sprintf("Add Flux %s component manifests", options.Version)
 	if b.commitMessageAppendix != "" {
 		commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix
@@ -311,7 +311,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options
 	b.logger.Successf("generated sync manifests")
 
 	// Git commit generated
-	gpgOpts := git.WithGpgSigningOption(b.gpgKeyPath, b.gpgPassphrase, b.gpgKeyID)
+	gpgOpts := git.WithGpgSigningOption(b.gpgKeyRingPath, b.gpgPassphrase, b.gpgKeyID)
 	commitMsg := fmt.Sprintf("Add Flux sync manifests")
 	if b.commitMessageAppendix != "" {
 		commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix
diff --git a/internal/bootstrap/git/commit_options.go b/internal/bootstrap/git/commit_options.go
index e1a9712c1beb5d835d19c63804aa3612ccf1a0df..e39614d20da26be6f48fc0b6e45ec9b62e84b07a 100644
--- a/internal/bootstrap/git/commit_options.go
+++ b/internal/bootstrap/git/commit_options.go
@@ -13,9 +13,9 @@ type CommitOptions struct {
 
 // GPGSigningInfo contains information for signing a commit.
 type GPGSigningInfo struct {
-	PrivateKeyPath string
-	Passphrase     string
-	KeyID          string
+	KeyRingPath string
+	Passphrase  string
+	KeyID       string
 }
 
 type GpgSigningOption struct {
@@ -27,11 +27,16 @@ func (w GpgSigningOption) ApplyToCommit(in *CommitOptions) {
 }
 
 func WithGpgSigningOption(path, passphrase, keyID string) Option {
+	// Return nil if no path is set, even if other options are configured.
+	if path == "" {
+		return GpgSigningOption{}
+	}
+
 	return GpgSigningOption{
 		GPGSigningInfo: &GPGSigningInfo{
-			PrivateKeyPath: path,
-			Passphrase:     passphrase,
-			KeyID:          keyID,
+			KeyRingPath: path,
+			Passphrase:  passphrase,
+			KeyID:       keyID,
 		},
 	}
 }
diff --git a/internal/bootstrap/git/gogit/gogit.go b/internal/bootstrap/git/gogit/gogit.go
index 333661d5b9caac5cfe50c378dc494ef1c369dd08..5525aeffc06d4ad7ffc13d856a6e03afef487ae6 100644
--- a/internal/bootstrap/git/gogit/gogit.go
+++ b/internal/bootstrap/git/gogit/gogit.go
@@ -258,9 +258,9 @@ func isRemoteBranchNotFoundErr(err error, ref string) bool {
 }
 
 func getOpenPgpEntity(info git.GPGSigningInfo) (*openpgp.Entity, error) {
-	r, err := os.Open(info.PrivateKeyPath)
+	r, err := os.Open(info.KeyRingPath)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("unable to open GPG key ring: %w", err)
 	}
 
 	entityList, err := openpgp.ReadKeyRing(r)
@@ -269,7 +269,7 @@ func getOpenPgpEntity(info git.GPGSigningInfo) (*openpgp.Entity, error) {
 	}
 
 	if len(entityList) == 0 {
-		return nil, fmt.Errorf("no entity formed")
+		return nil, fmt.Errorf("empty GPG key ring")
 	}
 
 	var entity *openpgp.Entity
@@ -281,7 +281,7 @@ func getOpenPgpEntity(info git.GPGSigningInfo) (*openpgp.Entity, error) {
 		}
 
 		if entity == nil {
-			return nil, fmt.Errorf("no key matching the key id was found")
+			return nil, fmt.Errorf("no GPG private key matching key id '%s' found", info.KeyID)
 		}
 	} else {
 		entity = entityList[0]
@@ -289,7 +289,7 @@ func getOpenPgpEntity(info git.GPGSigningInfo) (*openpgp.Entity, error) {
 
 	err = entity.PrivateKey.Decrypt([]byte(info.Passphrase))
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("unable to decrypt GPG private key: %w", err)
 	}
 
 	return entity, nil
diff --git a/internal/bootstrap/git/gogit/gogit_test.go b/internal/bootstrap/git/gogit/gogit_test.go
index 1c8bb3114d8dcfa709e1be6a9316faa86c8b9b77..b70cf8c362fef0635e6dcf1ff936647fd62fefde 100644
--- a/internal/bootstrap/git/gogit/gogit_test.go
+++ b/internal/bootstrap/git/gogit/gogit_test.go
@@ -49,9 +49,9 @@ func TestGetOpenPgpEntity(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			gpgInfo := git.GPGSigningInfo{
-				PrivateKeyPath: tt.keyPath,
-				Passphrase:     tt.passphrase,
-				KeyID:          tt.id,
+				KeyRingPath: tt.keyPath,
+				Passphrase:  tt.passphrase,
+				KeyID:       tt.id,
 			}
 
 			_, err := getOpenPgpEntity(gpgInfo)
diff --git a/internal/bootstrap/options.go b/internal/bootstrap/options.go
index 750f66e9e1a4badfe5ffadc626edca076bfa25da..0e95dba9ce486dcfc80c11dcf1e292188b35f194 100644
--- a/internal/bootstrap/options.go
+++ b/internal/bootstrap/options.go
@@ -115,21 +115,21 @@ func (o loggerOption) applyGitProvider(b *GitProviderBootstrapper) {
 
 func WithGitCommitSigning(path, passphrase, keyID string) Option {
 	return gitCommitSigningOption{
-		gpgKeyPath:    path,
-		gpgPassphrase: passphrase,
-		gpgKeyID:      keyID,
+		gpgKeyRingPath: path,
+		gpgPassphrase:  passphrase,
+		gpgKeyID:       keyID,
 	}
 }
 
 type gitCommitSigningOption struct {
-	gpgKeyPath    string
-	gpgPassphrase string
-	gpgKeyID      string
+	gpgKeyRingPath string
+	gpgPassphrase  string
+	gpgKeyID       string
 }
 
 func (o gitCommitSigningOption) applyGit(b *PlainGitBootstrapper) {
+	b.gpgKeyRingPath = o.gpgKeyRingPath
 	b.gpgPassphrase = o.gpgPassphrase
-	b.gpgKeyPath = o.gpgKeyPath
 	b.gpgKeyID = o.gpgKeyID
 }