Skip to content

Commit 5b76b03

Browse files
committed
feat: add oci kms
Signed-off-by: Peter Hrvola <[email protected]>
1 parent bb75c13 commit 5b76b03

File tree

12 files changed

+873
-114
lines changed

12 files changed

+873
-114
lines changed

README.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,22 @@ To easily deploy Vault locally: (DO NOT DO THIS FOR PRODUCTION!!!)
514514
515515
$ sops encrypt --verbose prod/raw.yaml > prod/encrypted.yaml
516516
517+
Encrypting using OCI KMS
518+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
519+
520+
We assume you are already have authentication profile set-up, ~/.oci/config exists and DEFAULT profile will be used to access OCI KMS. For details follow official OCI documentation.
521+
522+
.. code:: sh
523+
524+
$ # CRYPTO_ENDPOINT is diffrenet for different types of KMS and Regions, correct endpoint can be found in OCI console
525+
$ export CRYPTO_ENDPOINT=https://crypto.kms.eu-frankfurt-1.oraclecloud.com
526+
527+
$ export KEY_OCID=ocid1.key.xxxx
528+
$ export KEY_VERSION=ocid1.keyversion.xxxx
529+
530+
$ sops encrypt --oci-kms $CRYPTO_ENDPOINT/$KEY_OCID/$KEY_VERSION example.yaml
531+
532+
517533
Adding and removing keys
518534
~~~~~~~~~~~~~~~~~~~~~~~~
519535

cmd/sops/main.go

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/getsops/sops/v3/keyservice"
3939
"github.com/getsops/sops/v3/kms"
4040
"github.com/getsops/sops/v3/logging"
41+
"github.com/getsops/sops/v3/ocikms"
4142
"github.com/getsops/sops/v3/pgp"
4243
"github.com/getsops/sops/v3/stores/dotenv"
4344
"github.com/getsops/sops/v3/stores/json"
@@ -86,14 +87,14 @@ func main() {
8687
},
8788
}
8889
app.Name = "sops"
89-
app.Usage = "sops - encrypted file editor with AWS KMS, GCP KMS, Azure Key Vault, age, and GPG support"
90+
app.Usage = "sops - encrypted file editor with AWS KMS, GCP KMS, Azure Key Vault, OCI KMS, age, and GPG support"
9091
app.ArgsUsage = "sops [options] file"
9192
app.Version = version.Version
9293
app.Authors = []cli.Author{
9394
{Name: "CNCF Maintainers"},
9495
}
9596
app.UsageText = `sops is an editor of encrypted files that supports AWS KMS, GCP, AZKV,
96-
PGP, and Age
97+
OCI KMS, PGP, and Age
9798
9899
To encrypt or decrypt a document with AWS KMS, specify the KMS ARN
99100
in the -k flag or in the SOPS_KMS_ARN environment variable.
@@ -131,12 +132,12 @@ func main() {
131132
To use multiple KMS or PGP keys, separate them by commas. For example:
132133
$ sops -p "10F2...0A, 85D...B3F21" file.yaml
133134
134-
The -p, -k, --gcp-kms, --hc-vault-transit, and --azure-kv flags are only
135+
The -p, -k, --gcp-kms, --hc-vault-transit, --oci-kms, and --azure-kv flags are only
135136
used to encrypt new documents. Editing or decrypting existing documents
136137
can be done with "sops file" or "sops decrypt file" respectively. The KMS and
137138
PGP keys listed in the encrypted documents are used then. To manage master
138-
keys in existing documents, use the "add-{kms,pgp,gcp-kms,azure-kv,hc-vault-transit}"
139-
and "rm-{kms,pgp,gcp-kms,azure-kv,hc-vault-transit}" flags with --rotate
139+
keys in existing documents, use the "add-{kms,pgp,gcp-kms,azure-kv,oci-kms,hc-vault-transit}"
140+
and "rm-{kms,pgp,gcp-kms,azure-kv,oci-kms,hc-vault-transit}" flags with --rotate
140141
or the updatekeys command.
141142
142143
To use a different GPG binary than the one in your PATH, set SOPS_GPG_EXEC.
@@ -534,6 +535,10 @@ func main() {
534535
Name: "azure-kv",
535536
Usage: "the Azure Key Vault key URL the new group should contain. Can be specified more than once",
536537
},
538+
cli.StringSliceFlag{
539+
Name: "oci-kms",
540+
Usage: "the OCI KMS URL the new group should contain. Can be specified more than once",
541+
},
537542
cli.StringSliceFlag{
538543
Name: "hc-vault-transit",
539544
Usage: "the full vault path to the key used to encrypt/decrypt. Make you choose and configure a key with encryption/decryption enabled (e.g. 'https://vault.example.org:8200/v1/transit/keys/dev'). Can be specified more than once",
@@ -561,6 +566,7 @@ func main() {
561566
gcpKmses := c.StringSlice("gcp-kms")
562567
vaultURIs := c.StringSlice("hc-vault-transit")
563568
azkvs := c.StringSlice("azure-kv")
569+
ociKmses := c.StringSlice("oci-kms")
564570
ageRecipients := c.StringSlice("age")
565571
if c.NArg() != 0 {
566572
return common.NewExitError(fmt.Errorf("error: no positional arguments allowed"), codes.ErrorGeneric)
@@ -591,6 +597,14 @@ func main() {
591597
}
592598
group = append(group, k)
593599
}
600+
for _, uri := range ociKmses {
601+
k, err := azkv.NewMasterKeyFromURL(uri)
602+
if err != nil {
603+
log.WithError(err).Error("Failed to add key")
604+
continue
605+
}
606+
group = append(group, k)
607+
}
594608
for _, recipient := range ageRecipients {
595609
keys, err := age.MasterKeysFromRecipients(recipient)
596610
if err != nil {
@@ -898,6 +912,11 @@ func main() {
898912
Usage: "comma separated list of Azure Key Vault URLs",
899913
EnvVar: "SOPS_AZURE_KEYVAULT_URLS",
900914
},
915+
cli.StringFlag{
916+
Name: "oci-kms",
917+
Usage: "comma separated list of OCI KMS URLs",
918+
EnvVar: "SOPS_OCI_KMS_URLS",
919+
},
901920
cli.StringFlag{
902921
Name: "hc-vault-transit",
903922
Usage: "comma separated list of vault's key URI (e.g. 'https://vault.example.org:8200/v1/transit/keys/dev')",
@@ -1011,7 +1030,6 @@ func main() {
10111030
KeyServices: svcs,
10121031
encryptConfig: encConfig,
10131032
})
1014-
10151033
if err != nil {
10161034
return toExitError(err)
10171035
}
@@ -1086,6 +1104,14 @@ func main() {
10861104
Name: "rm-azure-kv",
10871105
Usage: "remove the provided comma-separated list of Azure Key Vault key URLs from the list of master keys on the given file",
10881106
},
1107+
cli.StringFlag{
1108+
Name: "add-oci-kms",
1109+
Usage: "add the provided comma-separated list of OCI KMS URL to the list of master keys on the given file",
1110+
},
1111+
cli.StringFlag{
1112+
Name: "rm-oci-kms",
1113+
Usage: "remove the provided comma-separated list of OCI KMS URL from the list of master keys on the given file",
1114+
},
10891115
cli.StringFlag{
10901116
Name: "add-kms",
10911117
Usage: "add the provided comma-separated list of KMS ARNs to the list of master keys on the given file",
@@ -1144,8 +1170,8 @@ func main() {
11441170
return toExitError(err)
11451171
}
11461172
if _, err := os.Stat(fileName); os.IsNotExist(err) {
1147-
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") != "" ||
1148-
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") != "" {
1173+
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-oci-kms") != "" || c.String("add-age") != "" ||
1174+
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-oci-kms") != "" || c.String("rm-age") != "" {
11491175
return common.NewExitError(fmt.Sprintf("Error: cannot add or remove keys on non-existent file %q, use the `edit` subcommand instead.", fileName), codes.CannotChangeKeysFromNonExistentFile)
11501176
}
11511177
}
@@ -1236,6 +1262,11 @@ func main() {
12361262
Usage: "comma separated list of Azure Key Vault URLs",
12371263
EnvVar: "SOPS_AZURE_KEYVAULT_URLS",
12381264
},
1265+
cli.StringFlag{
1266+
Name: "oci-kms",
1267+
Usage: "comma separated list of OCI KMS URLs",
1268+
EnvVar: "SOPS_OCI_KMS_URLS",
1269+
},
12391270
cli.StringFlag{
12401271
Name: "hc-vault-transit",
12411272
Usage: "comma separated list of vault's key URI (e.g. 'https://vault.example.org:8200/v1/transit/keys/dev')",
@@ -1610,6 +1641,11 @@ func main() {
16101641
Usage: "comma separated list of Azure Key Vault URLs",
16111642
EnvVar: "SOPS_AZURE_KEYVAULT_URLS",
16121643
},
1644+
cli.StringFlag{
1645+
Name: "oci-kms",
1646+
Usage: "comma separated list of OCI KMS resource OCIDs",
1647+
EnvVar: "SOPS_OCI_KMS_URLS",
1648+
},
16131649
cli.StringFlag{
16141650
Name: "hc-vault-transit",
16151651
Usage: "comma separated list of vault's key URI (e.g. 'https://vault.example.org:8200/v1/transit/keys/dev')",
@@ -1661,6 +1697,14 @@ func main() {
16611697
Name: "rm-azure-kv",
16621698
Usage: "remove the provided comma-separated list of Azure Key Vault key URLs from the list of master keys on the given file",
16631699
},
1700+
cli.StringFlag{
1701+
Name: "add-oci-kms",
1702+
Usage: "add the provided comma-separated list of OCI KMS URL to the list of master keys on the given file",
1703+
},
1704+
cli.StringFlag{
1705+
Name: "rm-oci-kms",
1706+
Usage: "remove the provided comma-separated list of OCI KMS URL from the list of master keys on the given file",
1707+
},
16641708
cli.StringFlag{
16651709
Name: "add-kms",
16661710
Usage: "add the provided comma-separated list of KMS ARNs to the list of master keys on the given file",
@@ -1787,8 +1831,8 @@ func main() {
17871831
return toExitError(err)
17881832
}
17891833
if _, err := os.Stat(fileName); os.IsNotExist(err) {
1790-
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") != "" ||
1791-
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") != "" {
1834+
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-oci-kms") != "" || c.String("add-age") != "" ||
1835+
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-oci-kms") != "" || c.String("rm-age") != "" {
17921836
return common.NewExitError(fmt.Sprintf("Error: cannot add or remove keys on non-existent file %q, use `--kms` and `--pgp` instead.", fileName), codes.CannotChangeKeysFromNonExistentFile)
17931837
}
17941838
if isEncryptMode || isDecryptMode || isRotateMode {
@@ -2081,7 +2125,7 @@ func getEncryptConfig(c *cli.Context, fileName string) (encryptConfig, error) {
20812125
}, nil
20822126
}
20832127

2084-
func getMasterKeys(c *cli.Context, kmsEncryptionContext map[string]*string, kmsOptionName string, pgpOptionName string, gcpKmsOptionName string, azureKvOptionName string, hcVaultTransitOptionName string, ageOptionName string) ([]keys.MasterKey, error) {
2128+
func getMasterKeys(c *cli.Context, kmsEncryptionContext map[string]*string, kmsOptionName string, pgpOptionName string, gcpKmsOptionName string, azureKvOptionName string, ociKmsOptionName, hcVaultTransitOptionName string, ageOptionName string) ([]keys.MasterKey, error) {
20852129
var masterKeys []keys.MasterKey
20862130
for _, k := range kms.MasterKeysFromArnString(c.String(kmsOptionName), kmsEncryptionContext, c.String("aws-profile")) {
20872131
masterKeys = append(masterKeys, k)
@@ -2092,6 +2136,13 @@ func getMasterKeys(c *cli.Context, kmsEncryptionContext map[string]*string, kmsO
20922136
for _, k := range gcpkms.MasterKeysFromResourceIDString(c.String(gcpKmsOptionName)) {
20932137
masterKeys = append(masterKeys, k)
20942138
}
2139+
ociKeys, err := ocikms.MasterKeysFromURLs(c.String(azureKvOptionName))
2140+
if err != nil {
2141+
return nil, err
2142+
}
2143+
for _, k := range ociKeys {
2144+
masterKeys = append(masterKeys, k)
2145+
}
20952146
azureKeys, err := azkv.MasterKeysFromURLs(c.String(azureKvOptionName))
20962147
if err != nil {
20972148
return nil, err
@@ -2118,11 +2169,11 @@ func getMasterKeys(c *cli.Context, kmsEncryptionContext map[string]*string, kmsO
21182169

21192170
func getRotateOpts(c *cli.Context, fileName string, inputStore common.Store, outputStore common.Store, svcs []keyservice.KeyServiceClient, decryptionOrder []string) (rotateOpts, error) {
21202171
kmsEncryptionContext := kms.ParseKMSContext(c.String("encryption-context"))
2121-
addMasterKeys, err := getMasterKeys(c, kmsEncryptionContext, "add-kms", "add-pgp", "add-gcp-kms", "add-azure-kv", "add-hc-vault-transit", "add-age")
2172+
addMasterKeys, err := getMasterKeys(c, kmsEncryptionContext, "add-kms", "add-pgp", "add-gcp-kms", "add-azure-kv", "add-oci-kms", "add-hc-vault-transit", "add-age")
21222173
if err != nil {
21232174
return rotateOpts{}, err
21242175
}
2125-
rmMasterKeys, err := getMasterKeys(c, kmsEncryptionContext, "rm-kms", "rm-pgp", "rm-gcp-kms", "rm-azure-kv", "rm-hc-vault-transit", "rm-age")
2176+
rmMasterKeys, err := getMasterKeys(c, kmsEncryptionContext, "rm-kms", "rm-pgp", "rm-gcp-kms", "rm-azure-kv", "rm-oci-kms", "rm-hc-vault-transit", "rm-age")
21262177
if err != nil {
21272178
return rotateOpts{}, err
21282179
}
@@ -2265,6 +2316,7 @@ func keyGroups(c *cli.Context, file string) ([]sops.KeyGroup, error) {
22652316
var pgpKeys []keys.MasterKey
22662317
var cloudKmsKeys []keys.MasterKey
22672318
var azkvKeys []keys.MasterKey
2319+
var ociKmsKeys []keys.MasterKey
22682320
var hcVaultMkKeys []keys.MasterKey
22692321
var ageMasterKeys []keys.MasterKey
22702322
kmsEncryptionContext := kms.ParseKMSContext(c.String("encryption-context"))
@@ -2290,6 +2342,16 @@ func keyGroups(c *cli.Context, file string) ([]sops.KeyGroup, error) {
22902342
azkvKeys = append(azkvKeys, k)
22912343
}
22922344
}
2345+
if c.String("oci-kms") != "" {
2346+
ociKeys, err := ocikms.MasterKeysFromURLs(c.String("oci-kms"))
2347+
if err != nil {
2348+
return nil, err
2349+
}
2350+
for _, k := range ociKeys {
2351+
ociKmsKeys = append(ociKmsKeys, k)
2352+
}
2353+
2354+
}
22932355
if c.String("hc-vault-transit") != "" {
22942356
hcVaultKeys, err := hcvault.NewMasterKeysFromURIs(c.String("hc-vault-transit"))
22952357
if err != nil {
@@ -2313,7 +2375,7 @@ func keyGroups(c *cli.Context, file string) ([]sops.KeyGroup, error) {
23132375
ageMasterKeys = append(ageMasterKeys, k)
23142376
}
23152377
}
2316-
if c.String("kms") == "" && c.String("pgp") == "" && c.String("gcp-kms") == "" && c.String("azure-kv") == "" && c.String("hc-vault-transit") == "" && c.String("age") == "" {
2378+
if c.String("kms") == "" && c.String("pgp") == "" && c.String("gcp-kms") == "" && c.String("azure-kv") == "" && c.String("oci-kms") == "" && c.String("hc-vault-transit") == "" && c.String("age") == "" {
23172379
conf, err := loadConfig(c, file, kmsEncryptionContext)
23182380
// config file might just not be supplied, without any error
23192381
if conf == nil {
@@ -2329,6 +2391,7 @@ func keyGroups(c *cli.Context, file string) ([]sops.KeyGroup, error) {
23292391
group = append(group, kmsKeys...)
23302392
group = append(group, cloudKmsKeys...)
23312393
group = append(group, azkvKeys...)
2394+
group = append(group, ociKmsKeys...)
23322395
group = append(group, pgpKeys...)
23332396
group = append(group, hcVaultMkKeys...)
23342397
group = append(group, ageMasterKeys...)

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ require (
2828
github.com/lib/pq v1.10.9
2929
github.com/mitchellh/go-homedir v1.1.0
3030
github.com/mitchellh/go-wordwrap v1.0.1
31+
github.com/oracle/oci-go-sdk/v65 v65.92.0
3132
github.com/ory/dockertest/v3 v3.12.0
3233
github.com/pkg/errors v0.9.1
3334
github.com/sirupsen/logrus v1.9.3
@@ -97,6 +98,7 @@ require (
9798
github.com/go-logr/logr v1.4.2 // indirect
9899
github.com/go-logr/stdr v1.2.2 // indirect
99100
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
101+
github.com/gofrs/flock v0.8.1 // indirect
100102
github.com/gogo/protobuf v1.3.2 // indirect
101103
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
102104
github.com/google/s2a-go v0.1.9 // indirect
@@ -126,10 +128,12 @@ require (
126128
github.com/pmezard/go-difflib v1.0.0 // indirect
127129
github.com/russross/blackfriday/v2 v2.1.0 // indirect
128130
github.com/ryanuber/go-glob v1.0.0 // indirect
131+
github.com/sony/gobreaker v0.5.0 // indirect
129132
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
130133
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
131134
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
132135
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
136+
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
133137
github.com/zeebo/errs v1.4.0 // indirect
134138
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
135139
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect

0 commit comments

Comments
 (0)