@@ -170,23 +170,86 @@ type destinationRule struct {
170170}
171171
172172type creationRule struct {
173- PathRegex string `yaml:"path_regex"`
174- KMS string
175- AwsProfile string `yaml:"aws_profile"`
176- Age string `yaml:"age"`
177- PGP string
178- GCPKMS string `yaml:"gcp_kms"`
179- AzureKeyVault string `yaml:"azure_keyvault"`
180- VaultURI string `yaml:"hc_vault_transit_uri"`
181- KeyGroups []keyGroup `yaml:"key_groups"`
182- ShamirThreshold int `yaml:"shamir_threshold"`
183- UnencryptedSuffix string `yaml:"unencrypted_suffix"`
184- EncryptedSuffix string `yaml:"encrypted_suffix"`
185- UnencryptedRegex string `yaml:"unencrypted_regex"`
186- EncryptedRegex string `yaml:"encrypted_regex"`
187- UnencryptedCommentRegex string `yaml:"unencrypted_comment_regex"`
188- EncryptedCommentRegex string `yaml:"encrypted_comment_regex"`
189- MACOnlyEncrypted bool `yaml:"mac_only_encrypted"`
173+ PathRegex string `yaml:"path_regex"`
174+ KMS interface {} `yaml:"kms"` // string or []string
175+ AwsProfile string `yaml:"aws_profile"`
176+ Age interface {} `yaml:"age"` // string or []string
177+ PGP interface {} `yaml:"pgp"` // string or []string
178+ GCPKMS interface {} `yaml:"gcp_kms"` // string or []string
179+ AzureKeyVault interface {} `yaml:"azure_keyvault"` // string or []string
180+ VaultURI interface {} `yaml:"hc_vault_transit_uri"` // string or []string
181+ KeyGroups []keyGroup `yaml:"key_groups"`
182+ ShamirThreshold int `yaml:"shamir_threshold"`
183+ UnencryptedSuffix string `yaml:"unencrypted_suffix"`
184+ EncryptedSuffix string `yaml:"encrypted_suffix"`
185+ UnencryptedRegex string `yaml:"unencrypted_regex"`
186+ EncryptedRegex string `yaml:"encrypted_regex"`
187+ UnencryptedCommentRegex string `yaml:"unencrypted_comment_regex"`
188+ EncryptedCommentRegex string `yaml:"encrypted_comment_regex"`
189+ MACOnlyEncrypted bool `yaml:"mac_only_encrypted"`
190+ }
191+
192+ // Helper methods to safely extract keys as []string
193+ func (c * creationRule ) GetKMSKeys () ([]string , error ) {
194+ return parseKeyField (c .KMS , "kms" )
195+ }
196+
197+ func (c * creationRule ) GetAgeKeys () ([]string , error ) {
198+ return parseKeyField (c .Age , "age" )
199+ }
200+
201+ func (c * creationRule ) GetPGPKeys () ([]string , error ) {
202+ return parseKeyField (c .PGP , "pgp" )
203+ }
204+
205+ func (c * creationRule ) GetGCPKMSKeys () ([]string , error ) {
206+ return parseKeyField (c .GCPKMS , "gcp_kms" )
207+ }
208+
209+ func (c * creationRule ) GetAzureKeyVaultKeys () ([]string , error ) {
210+ return parseKeyField (c .AzureKeyVault , "azure_keyvault" )
211+ }
212+
213+ func (c * creationRule ) GetVaultURIs () ([]string , error ) {
214+ return parseKeyField (c .VaultURI , "hc_vault_transit_uri" )
215+ }
216+
217+ // Utility function to handle both string and []string
218+ func parseKeyField (field interface {}, fieldName string ) ([]string , error ) {
219+ if field == nil {
220+ return []string {}, nil
221+ }
222+
223+ switch v := field .(type ) {
224+ case string :
225+ if v == "" {
226+ return []string {}, nil
227+ }
228+ // Existing CSV parsing logic
229+ keys := strings .Split (v , "," )
230+ result := make ([]string , 0 , len (keys ))
231+ for _ , key := range keys {
232+ trimmed := strings .TrimSpace (key )
233+ if trimmed != "" { // Skip empty strings (fixes trailing comma issue)
234+ result = append (result , trimmed )
235+ }
236+ }
237+ return result , nil
238+ case []interface {}:
239+ result := make ([]string , len (v ))
240+ for i , item := range v {
241+ if str , ok := item .(string ); ok {
242+ result [i ] = str
243+ } else {
244+ return nil , fmt .Errorf ("invalid %s key configuration: expected string in list, got %T" , fieldName , item )
245+ }
246+ }
247+ return result , nil
248+ case []string :
249+ return v , nil
250+ default :
251+ return nil , fmt .Errorf ("invalid %s key configuration: expected string, []string, or nil, got %T" , fieldName , field )
252+ }
190253}
191254
192255func NewStoresConfig () * StoresConfig {
@@ -279,6 +342,14 @@ func extractMasterKeys(group keyGroup) (sops.KeyGroup, error) {
279342 return deduplicateKeygroup (keyGroup ), nil
280343}
281344
345+ func getKeysWithValidation (getKeysFunc func () ([]string , error ), keyType string ) ([]string , error ) {
346+ keys , err := getKeysFunc ()
347+ if err != nil {
348+ return nil , fmt .Errorf ("invalid %s key configuration: %w" , keyType , err )
349+ }
350+ return keys , nil
351+ }
352+
282353func getKeyGroupsFromCreationRule (cRule * creationRule , kmsEncryptionContext map [string ]* string ) ([]sops.KeyGroup , error ) {
283354 var groups []sops.KeyGroup
284355 if len (cRule .KeyGroups ) > 0 {
@@ -291,8 +362,13 @@ func getKeyGroupsFromCreationRule(cRule *creationRule, kmsEncryptionContext map[
291362 }
292363 } else {
293364 var keyGroup sops.KeyGroup
294- if cRule .Age != "" {
295- ageKeys , err := age .MasterKeysFromRecipients (cRule .Age )
365+ ageKeys , err := getKeysWithValidation (cRule .GetAgeKeys , "age" )
366+ if err != nil {
367+ return nil , err
368+ }
369+
370+ if len (ageKeys ) > 0 {
371+ ageKeys , err := age .MasterKeysFromRecipients (strings .Join (ageKeys , "," ))
296372 if err != nil {
297373 return nil , err
298374 } else {
@@ -301,23 +377,43 @@ func getKeyGroupsFromCreationRule(cRule *creationRule, kmsEncryptionContext map[
301377 }
302378 }
303379 }
304- for _ , k := range pgp .MasterKeysFromFingerprintString (cRule .PGP ) {
380+ pgpKeys , err := getKeysWithValidation (cRule .GetPGPKeys , "pgp" )
381+ if err != nil {
382+ return nil , err
383+ }
384+ for _ , k := range pgp .MasterKeysFromFingerprintString (strings .Join (pgpKeys , "," )) {
305385 keyGroup = append (keyGroup , k )
306386 }
307- for _ , k := range kms .MasterKeysFromArnString (cRule .KMS , kmsEncryptionContext , cRule .AwsProfile ) {
387+ kmsKeys , err := getKeysWithValidation (cRule .GetKMSKeys , "kms" )
388+ if err != nil {
389+ return nil , err
390+ }
391+ for _ , k := range kms .MasterKeysFromArnString (strings .Join (kmsKeys , "," ), kmsEncryptionContext , cRule .AwsProfile ) {
308392 keyGroup = append (keyGroup , k )
309393 }
310- for _ , k := range gcpkms .MasterKeysFromResourceIDString (cRule .GCPKMS ) {
394+ gcpkmsKeys , err := getKeysWithValidation (cRule .GetGCPKMSKeys , "gcpkms" )
395+ if err != nil {
396+ return nil , err
397+ }
398+ for _ , k := range gcpkms .MasterKeysFromResourceIDString (strings .Join (gcpkmsKeys , "," )) {
311399 keyGroup = append (keyGroup , k )
312400 }
313- azureKeys , err := azkv .MasterKeysFromURLs (cRule .AzureKeyVault )
401+ azKeys , err := getKeysWithValidation (cRule .GetAzureKeyVaultKeys , "azure_keyvault" )
402+ if err != nil {
403+ return nil , err
404+ }
405+ azureKeys , err := azkv .MasterKeysFromURLs (strings .Join (azKeys , "," ))
314406 if err != nil {
315407 return nil , err
316408 }
317409 for _ , k := range azureKeys {
318410 keyGroup = append (keyGroup , k )
319411 }
320- vaultKeys , err := hcvault .NewMasterKeysFromURIs (cRule .VaultURI )
412+ vaultKeyUris , err := getKeysWithValidation (cRule .GetVaultURIs , "vault" )
413+ if err != nil {
414+ return nil , err
415+ }
416+ vaultKeys , err := hcvault .NewMasterKeysFromURIs (strings .Join (vaultKeyUris , "," ))
321417 if err != nil {
322418 return nil , err
323419 }
0 commit comments