Skip to content

Commit 72e903e

Browse files
committed
feat: Add HuaweiCloud KMS support
Signed-off-by: Enbiya Goral <100806254+enbiyagoral@users.noreply.github.com>
1 parent 07ded6f commit 72e903e

18 files changed

Lines changed: 1195 additions & 263 deletions

File tree

.github/workflows/cli.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ jobs:
2929
VAULT_ADDR: "http://127.0.0.1:8200"
3030
steps:
3131
- name: Set up Go ${{ matrix.go-version }}
32-
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
32+
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
3333
with:
3434
go-version: ${{ matrix.go-version }}
3535
id: go
3636

3737
- name: Check out code into the Go module directory
38-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
38+
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
3939
with:
4040
persist-credentials: false
4141

@@ -92,7 +92,7 @@ jobs:
9292
VAULT_ADDR: "http://127.0.0.1:8200"
9393
steps:
9494
- name: Check out code
95-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
95+
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
9696
with:
9797
persist-credentials: false
9898

.github/workflows/codeql.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ jobs:
2929

3030
steps:
3131
- name: Checkout code
32-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
32+
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
3333
with:
3434
persist-credentials: false
3535

3636
# Initializes the CodeQL tools for scanning.
3737
- name: Initialize CodeQL
38-
uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
38+
uses: github/codeql-action/init@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
3939
with:
4040
languages: go
4141
# xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
@@ -52,6 +52,6 @@ jobs:
5252
make install
5353
5454
- name: Perform CodeQL Analysis
55-
uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
55+
uses: github/codeql-action/analyze@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
5656
with:
5757
category: "/language:go"

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323

2424
steps:
2525
- name: Checkout code
26-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
26+
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
2727
with:
2828
persist-credentials: false
2929

.github/workflows/linters.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
runs-on: ubuntu-latest
2222
steps:
2323
- name: Check out code
24-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
24+
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
2525
with:
2626
persist-credentials: false
2727

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ jobs:
2525

2626
steps:
2727
- name: Checkout
28-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
28+
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
2929
with:
3030
fetch-depth: 0
3131
persist-credentials: false
3232

3333
- name: Setup Go
34-
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v4.0.1
34+
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v4.0.1
3535
with:
3636
go-version: 1.25
3737
cache: false
3838

3939
- name: Setup Syft
40-
uses: anchore/sbom-action/download-syft@8e94d75ddd33f69f691467e42275782e4bfefe84 # v0.20.9
40+
uses: anchore/sbom-action/download-syft@fbfd9c6c189226748411491745178e0c2017392d # v0.20.10
4141

4242
- name: Setup Cosign
4343
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0

README.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,10 +1013,12 @@ try all other remote key services until one succeeds.
10131013
10141014
You can start a key service server by running ``sops keyservice``.
10151015
1016-
You can specify the key services the ``sops`` binary uses with ``--keyservice``.
1017-
This flag can be specified more than once, so you can use multiple key
1018-
services. The local key service can be disabled with
1019-
``enable-local-keyservice=false``.
1016+
You can specify the key services the ``sops`` binary uses with the
1017+
``--keyservice`` option. This flag can be specified more than once, so you can
1018+
use multiple key services. Alternatively, a single key service can be specified
1019+
by setting the ``SOPS_KEYSERVICE`` environment variable. The local key service
1020+
can be disabled with ``--enable-local-keyservice=false`` or by setting the
1021+
``SOPS_ENABLE_LOCAL_KEYSERVICE`` environment variable to ``false``.
10201022
10211023
For example, to decrypt a file using both the local key service and the key
10221024
service exposed on the unix socket located in ``/tmp/sops.sock``, you can run:

cmd/sops/main.go

Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/getsops/sops/v3/cmd/sops/subcommand/updatekeys"
3535
"github.com/getsops/sops/v3/config"
3636
"github.com/getsops/sops/v3/gcpkms"
37+
"github.com/getsops/sops/v3/hckms"
3738
"github.com/getsops/sops/v3/hcvault"
3839
"github.com/getsops/sops/v3/keys"
3940
"github.com/getsops/sops/v3/keyservice"
@@ -90,13 +91,13 @@ func main() {
9091
},
9192
}
9293
app.Name = "sops"
93-
app.Usage = "sops - encrypted file editor with AWS KMS, GCP KMS, Azure Key Vault, age, and GPG support"
94+
app.Usage = "sops - encrypted file editor with AWS KMS, GCP KMS, HuaweiCloud KMS, Azure Key Vault, age, and GPG support"
9495
app.ArgsUsage = "sops [options] file"
9596
app.Version = version.Version
9697
app.Authors = []cli.Author{
9798
{Name: "CNCF Maintainers"},
9899
}
99-
app.UsageText = `sops is an editor of encrypted files that supports AWS KMS, GCP, AZKV,
100+
app.UsageText = `sops is an editor of encrypted files that supports AWS KMS, GCP, HuaweiCloud KMS, AZKV,
100101
PGP, and Age
101102
102103
To encrypt or decrypt a document with AWS KMS, specify the KMS ARN
@@ -109,6 +110,12 @@ func main() {
109110
(You need to setup Google application default credentials. See
110111
https://developers.google.com/identity/protocols/application-default-credentials)
111112
113+
To encrypt or decrypt a document with HuaweiCloud KMS, specify the
114+
HuaweiCloud KMS key ID (format: region:key-uuid) in the --hckms flag or in the
115+
SOPS_HUAWEICLOUD_KMS_IDS environment variable.
116+
(You need to setup HuaweiCloud credentials via environment variables:
117+
HUAWEICLOUD_SDK_AK, HUAWEICLOUD_SDK_SK, HUAWEICLOUD_SDK_PROJECT_ID, or
118+
use credentials file at ~/.huaweicloud/credentials)
112119
113120
To encrypt or decrypt a document with HashiCorp Vault's Transit Secret
114121
Engine, specify the Vault key URI name in the --hc-vault-transit flag
@@ -135,12 +142,12 @@ func main() {
135142
To use multiple KMS or PGP keys, separate them by commas. For example:
136143
$ sops -p "10F2...0A, 85D...B3F21" file.yaml
137144
138-
The -p, -k, --gcp-kms, --hc-vault-transit, and --azure-kv flags are only
145+
The -p, -k, --gcp-kms, --hckms, --hc-vault-transit, and --azure-kv flags are only
139146
used to encrypt new documents. Editing or decrypting existing documents
140147
can be done with "sops file" or "sops decrypt file" respectively. The KMS and
141148
PGP keys listed in the encrypted documents are used then. To manage master
142-
keys in existing documents, use the "add-{kms,pgp,gcp-kms,azure-kv,hc-vault-transit}"
143-
and "rm-{kms,pgp,gcp-kms,azure-kv,hc-vault-transit}" flags with --rotate
149+
keys in existing documents, use the "add-{kms,pgp,gcp-kms,hckms,azure-kv,hc-vault-transit}"
150+
and "rm-{kms,pgp,gcp-kms,hckms,azure-kv,hc-vault-transit}" flags with --rotate
144151
or the updatekeys command.
145152
146153
To use a different GPG binary than the one in your PATH, set SOPS_GPG_EXEC.
@@ -570,6 +577,10 @@ func main() {
570577
Name: "gcp-kms",
571578
Usage: "the GCP KMS Resource ID the new group should contain. Can be specified more than once",
572579
},
580+
cli.StringSliceFlag{
581+
Name: "hckms",
582+
Usage: "the HuaweiCloud KMS key ID (format: region:key-uuid) the new group should contain. Can be specified more than once",
583+
},
573584
cli.StringSliceFlag{
574585
Name: "azure-kv",
575586
Usage: "the Azure Key Vault key URL the new group should contain. Can be specified more than once",
@@ -933,6 +944,11 @@ func main() {
933944
Usage: "comma separated list of GCP KMS resource IDs",
934945
EnvVar: "SOPS_GCP_KMS_IDS",
935946
},
947+
cli.StringFlag{
948+
Name: "hckms",
949+
Usage: "comma separated list of HuaweiCloud KMS key IDs (format: region:key-uuid)",
950+
EnvVar: "SOPS_HUAWEICLOUD_KMS_IDS",
951+
},
936952
cli.StringFlag{
937953
Name: "azure-kv",
938954
Usage: "comma separated list of Azure Key Vault URLs",
@@ -1118,6 +1134,14 @@ func main() {
11181134
Name: "rm-gcp-kms",
11191135
Usage: "remove the provided comma-separated list of GCP KMS key resource IDs from the list of master keys on the given file",
11201136
},
1137+
cli.StringFlag{
1138+
Name: "add-hckms",
1139+
Usage: "add the provided comma-separated list of HuaweiCloud KMS key IDs (format: region:key-uuid) to the list of master keys on the given file",
1140+
},
1141+
cli.StringFlag{
1142+
Name: "rm-hckms",
1143+
Usage: "remove the provided comma-separated list of HuaweiCloud KMS key IDs (format: region:key-uuid) from the list of master keys on the given file",
1144+
},
11211145
cli.StringFlag{
11221146
Name: "add-azure-kv",
11231147
Usage: "add the provided comma-separated list of Azure Key Vault key URLs to the list of master keys on the given file",
@@ -1184,8 +1208,8 @@ func main() {
11841208
return toExitError(err)
11851209
}
11861210
if _, err := os.Stat(fileName); os.IsNotExist(err) {
1187-
if c.String("add-kms") != "" || c.String("add-pgp") != "" || c.String("add-gcp-kms") != "" || c.String("add-hc-vault-transit") != "" || c.String("add-azure-kv") != "" || c.String("add-age") != "" ||
1188-
c.String("rm-kms") != "" || c.String("rm-pgp") != "" || c.String("rm-gcp-kms") != "" || c.String("rm-hc-vault-transit") != "" || c.String("rm-azure-kv") != "" || c.String("rm-age") != "" {
1211+
if c.String("add-kms") != "" || c.String("add-pgp") != "" || c.String("add-gcp-kms") != "" || c.String("add-hckms") != "" || c.String("add-hc-vault-transit") != "" || c.String("add-azure-kv") != "" || c.String("add-age") != "" ||
1212+
c.String("rm-kms") != "" || c.String("rm-pgp") != "" || c.String("rm-gcp-kms") != "" || c.String("rm-hckms") != "" || c.String("rm-hc-vault-transit") != "" || c.String("rm-azure-kv") != "" || c.String("rm-age") != "" {
11891213
return common.NewExitError(fmt.Sprintf("Error: cannot add or remove keys on non-existent file %q, use the `edit` subcommand instead.", fileName), codes.CannotChangeKeysFromNonExistentFile)
11901214
}
11911215
}
@@ -1271,6 +1295,11 @@ func main() {
12711295
Usage: "comma separated list of GCP KMS resource IDs",
12721296
EnvVar: "SOPS_GCP_KMS_IDS",
12731297
},
1298+
cli.StringFlag{
1299+
Name: "hckms",
1300+
Usage: "comma separated list of HuaweiCloud KMS key IDs (format: region:key-uuid)",
1301+
EnvVar: "SOPS_HUAWEICLOUD_KMS_IDS",
1302+
},
12741303
cli.StringFlag{
12751304
Name: "azure-kv",
12761305
Usage: "comma separated list of Azure Key Vault URLs",
@@ -1679,6 +1708,11 @@ func main() {
16791708
Usage: "comma separated list of GCP KMS resource IDs",
16801709
EnvVar: "SOPS_GCP_KMS_IDS",
16811710
},
1711+
cli.StringFlag{
1712+
Name: "hckms",
1713+
Usage: "comma separated list of HuaweiCloud KMS key IDs (format: region:key-uuid)",
1714+
EnvVar: "SOPS_HUAWEICLOUD_KMS_IDS",
1715+
},
16821716
cli.StringFlag{
16831717
Name: "azure-kv",
16841718
Usage: "comma separated list of Azure Key Vault URLs",
@@ -1727,6 +1761,14 @@ func main() {
17271761
Name: "rm-gcp-kms",
17281762
Usage: "remove the provided comma-separated list of GCP KMS key resource IDs from the list of master keys on the given file",
17291763
},
1764+
cli.StringFlag{
1765+
Name: "add-hckms",
1766+
Usage: "add the provided comma-separated list of HuaweiCloud KMS key IDs (format: region:key-uuid) to the list of master keys on the given file",
1767+
},
1768+
cli.StringFlag{
1769+
Name: "rm-hckms",
1770+
Usage: "remove the provided comma-separated list of HuaweiCloud KMS key IDs (format: region:key-uuid) from the list of master keys on the given file",
1771+
},
17301772
cli.StringFlag{
17311773
Name: "add-azure-kv",
17321774
Usage: "add the provided comma-separated list of Azure Key Vault key URLs to the list of master keys on the given file",
@@ -1861,8 +1903,8 @@ func main() {
18611903
return toExitError(err)
18621904
}
18631905
if _, err := os.Stat(fileName); os.IsNotExist(err) {
1864-
if c.String("add-kms") != "" || c.String("add-pgp") != "" || c.String("add-gcp-kms") != "" || c.String("add-hc-vault-transit") != "" || c.String("add-azure-kv") != "" || c.String("add-age") != "" ||
1865-
c.String("rm-kms") != "" || c.String("rm-pgp") != "" || c.String("rm-gcp-kms") != "" || c.String("rm-hc-vault-transit") != "" || c.String("rm-azure-kv") != "" || c.String("rm-age") != "" {
1906+
if c.String("add-kms") != "" || c.String("add-pgp") != "" || c.String("add-gcp-kms") != "" || c.String("add-hckms") != "" || c.String("add-hc-vault-transit") != "" || c.String("add-azure-kv") != "" || c.String("add-age") != "" ||
1907+
c.String("rm-kms") != "" || c.String("rm-pgp") != "" || c.String("rm-gcp-kms") != "" || c.String("rm-hckms") != "" || c.String("rm-hc-vault-transit") != "" || c.String("rm-azure-kv") != "" || c.String("rm-age") != "" {
18661908
return common.NewExitError(fmt.Sprintf("Error: cannot add or remove keys on non-existent file %q, use `--kms` and `--pgp` instead.", fileName), codes.CannotChangeKeysFromNonExistentFile)
18671909
}
18681910
if isEncryptMode || isDecryptMode || isRotateMode {
@@ -2191,7 +2233,7 @@ func getEncryptConfig(c *cli.Context, fileName string, inputStore common.Store,
21912233
}, nil
21922234
}
21932235

2194-
func getMasterKeys(c *cli.Context, kmsEncryptionContext map[string]*string, kmsOptionName string, pgpOptionName string, gcpKmsOptionName string, azureKvOptionName string, hcVaultTransitOptionName string, ageOptionName string) ([]keys.MasterKey, error) {
2236+
func getMasterKeys(c *cli.Context, kmsEncryptionContext map[string]*string, kmsOptionName string, pgpOptionName string, gcpKmsOptionName string, hckmsOptionName string, azureKvOptionName string, hcVaultTransitOptionName string, ageOptionName string) ([]keys.MasterKey, error) {
21952237
var masterKeys []keys.MasterKey
21962238
for _, k := range kms.MasterKeysFromArnString(c.String(kmsOptionName), kmsEncryptionContext, c.String("aws-profile")) {
21972239
masterKeys = append(masterKeys, k)
@@ -2202,6 +2244,13 @@ func getMasterKeys(c *cli.Context, kmsEncryptionContext map[string]*string, kmsO
22022244
for _, k := range gcpkms.MasterKeysFromResourceIDString(c.String(gcpKmsOptionName)) {
22032245
masterKeys = append(masterKeys, k)
22042246
}
2247+
hckmsKeys, err := hckms.NewMasterKeyFromKeyIDString(c.String(hckmsOptionName))
2248+
if err != nil {
2249+
return nil, err
2250+
}
2251+
for _, k := range hckmsKeys {
2252+
masterKeys = append(masterKeys, k)
2253+
}
22052254
azureKeys, err := azkv.MasterKeysFromURLs(c.String(azureKvOptionName))
22062255
if err != nil {
22072256
return nil, err
@@ -2228,11 +2277,11 @@ func getMasterKeys(c *cli.Context, kmsEncryptionContext map[string]*string, kmsO
22282277

22292278
func getRotateOpts(c *cli.Context, fileName string, inputStore common.Store, outputStore common.Store, svcs []keyservice.KeyServiceClient, decryptionOrder []string) (rotateOpts, error) {
22302279
kmsEncryptionContext := kms.ParseKMSContext(c.String("encryption-context"))
2231-
addMasterKeys, err := getMasterKeys(c, kmsEncryptionContext, "add-kms", "add-pgp", "add-gcp-kms", "add-azure-kv", "add-hc-vault-transit", "add-age")
2280+
addMasterKeys, err := getMasterKeys(c, kmsEncryptionContext, "add-kms", "add-pgp", "add-gcp-kms", "add-hckms", "add-azure-kv", "add-hc-vault-transit", "add-age")
22322281
if err != nil {
22332282
return rotateOpts{}, err
22342283
}
2235-
rmMasterKeys, err := getMasterKeys(c, kmsEncryptionContext, "rm-kms", "rm-pgp", "rm-gcp-kms", "rm-azure-kv", "rm-hc-vault-transit", "rm-age")
2284+
rmMasterKeys, err := getMasterKeys(c, kmsEncryptionContext, "rm-kms", "rm-pgp", "rm-gcp-kms", "rm-hckms", "rm-azure-kv", "rm-hc-vault-transit", "rm-age")
22362285
if err != nil {
22372286
return rotateOpts{}, err
22382287
}
@@ -2380,6 +2429,7 @@ func keyGroups(c *cli.Context, file string, optionalConfig *config.Config) ([]so
23802429
var cloudKmsKeys []keys.MasterKey
23812430
var azkvKeys []keys.MasterKey
23822431
var hcVaultMkKeys []keys.MasterKey
2432+
var hckmsMkKeys []keys.MasterKey
23832433
var ageMasterKeys []keys.MasterKey
23842434
kmsEncryptionContext := kms.ParseKMSContext(c.String("encryption-context"))
23852435
if c.String("encryption-context") != "" && kmsEncryptionContext == nil {
@@ -2395,6 +2445,15 @@ func keyGroups(c *cli.Context, file string, optionalConfig *config.Config) ([]so
23952445
cloudKmsKeys = append(cloudKmsKeys, k)
23962446
}
23972447
}
2448+
if c.String("hckms") != "" {
2449+
hckmsKeys, err := hckms.NewMasterKeyFromKeyIDString(c.String("hckms"))
2450+
if err != nil {
2451+
return nil, err
2452+
}
2453+
for _, k := range hckmsKeys {
2454+
hckmsMkKeys = append(hckmsMkKeys, k)
2455+
}
2456+
}
23982457
if c.String("azure-kv") != "" {
23992458
azureKeys, err := azkv.MasterKeysFromURLs(c.String("azure-kv"))
24002459
if err != nil {
@@ -2427,7 +2486,7 @@ func keyGroups(c *cli.Context, file string, optionalConfig *config.Config) ([]so
24272486
ageMasterKeys = append(ageMasterKeys, k)
24282487
}
24292488
}
2430-
if c.String("kms") == "" && c.String("pgp") == "" && c.String("gcp-kms") == "" && c.String("azure-kv") == "" && c.String("hc-vault-transit") == "" && c.String("age") == "" {
2489+
if c.String("kms") == "" && c.String("pgp") == "" && c.String("gcp-kms") == "" && c.String("hckms") == "" && c.String("azure-kv") == "" && c.String("hc-vault-transit") == "" && c.String("age") == "" {
24312490
conf := optionalConfig
24322491
var err error
24332492
if conf == nil {
@@ -2446,6 +2505,7 @@ func keyGroups(c *cli.Context, file string, optionalConfig *config.Config) ([]so
24462505
var group sops.KeyGroup
24472506
group = append(group, kmsKeys...)
24482507
group = append(group, cloudKmsKeys...)
2508+
group = append(group, hckmsMkKeys...)
24492509
group = append(group, azkvKeys...)
24502510
group = append(group, pgpKeys...)
24512511
group = append(group, hcVaultMkKeys...)

0 commit comments

Comments
 (0)