1
0
mirror of https://github.com/getsops/sops.git synced 2026-02-05 12:45:21 +01:00

AWS Profiles

This commit is contained in:
Mark Kelly
2019-01-25 12:42:41 +00:00
parent 988e49994d
commit ac5ca1f05c
9 changed files with 56 additions and 20 deletions

View File

@@ -326,6 +326,23 @@ When removing keys, it is recommended to rotate the data key using ``-r``,
otherwise owners of the removed key may have add access to the data key in the
past.
KMS AWS Profiles
~~~~~~~~~~~~~~~~
If you want to use a specific profile, you can do so with `aws_profile`:
.. code:: yaml
sops:
kms:
- arn: arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e
aws_profile: foo
If no AWS profile is set, default credentials will be used.
Similarly the `--aws-profile` flag can be set with the command line with any of the KMS commands.
Assuming roles and using KMS in various AWS accounts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -29,11 +29,11 @@ import (
"go.mozilla.org/sops/logging"
"go.mozilla.org/sops/pgp"
"go.mozilla.org/sops/stores/dotenv"
"go.mozilla.org/sops/stores/ini"
"go.mozilla.org/sops/stores/json"
yamlstores "go.mozilla.org/sops/stores/yaml"
"google.golang.org/grpc"
"gopkg.in/urfave/cli.v1"
"go.mozilla.org/sops/stores/ini"
)
var log *logrus.Logger
@@ -161,6 +161,10 @@ func main() {
Name: "kms",
Usage: "the KMS ARNs the new group should contain. Can be specified more than once",
},
cli.StringFlag{
Name: "aws-profile",
Usage: "The AWS profile to use for requests to AWS",
},
cli.StringSliceFlag{
Name: "gcp-kms",
Usage: "the GCP KMS Resource ID the new group should contain. Can be specified more than once",
@@ -192,7 +196,7 @@ func main() {
group = append(group, pgp.NewMasterKeyFromFingerprint(fp))
}
for _, arn := range kmsArns {
group = append(group, kms.NewMasterKeyFromArn(arn, kms.ParseKMSContext(c.String("encryption-context"))))
group = append(group, kms.NewMasterKeyFromArn(arn, kms.ParseKMSContext(c.String("encryption-context")), c.String("aws-profile")))
}
for _, kms := range gcpKmses {
group = append(group, gcpkms.NewMasterKeyFromResourceID(kms))
@@ -305,6 +309,10 @@ func main() {
Usage: "comma separated list of KMS ARNs",
EnvVar: "SOPS_KMS_ARN",
},
cli.StringFlag{
Name: "aws-profile",
Usage: "The AWS profile to use for requests to AWS",
},
cli.StringFlag{
Name: "gcp-kms",
Usage: "comma separated list of GCP KMS resource IDs",
@@ -502,7 +510,7 @@ func main() {
if c.Bool("rotate") {
var addMasterKeys []keys.MasterKey
kmsEncryptionContext := kms.ParseKMSContext(c.String("encryption-context"))
for _, k := range kms.MasterKeysFromArnString(c.String("add-kms"), kmsEncryptionContext) {
for _, k := range kms.MasterKeysFromArnString(c.String("add-kms"), kmsEncryptionContext, c.String("aws-profile")) {
addMasterKeys = append(addMasterKeys, k)
}
for _, k := range pgp.MasterKeysFromFingerprintString(c.String("add-pgp")) {
@@ -520,7 +528,7 @@ func main() {
}
var rmMasterKeys []keys.MasterKey
for _, k := range kms.MasterKeysFromArnString(c.String("rm-kms"), kmsEncryptionContext) {
for _, k := range kms.MasterKeysFromArnString(c.String("rm-kms"), kmsEncryptionContext, c.String("aws-profile")) {
rmMasterKeys = append(rmMasterKeys, k)
}
for _, k := range pgp.MasterKeysFromFingerprintString(c.String("rm-pgp")) {
@@ -754,7 +762,7 @@ func keyGroups(c *cli.Context, file string) ([]sops.KeyGroup, error) {
return nil, common.NewExitError("Invalid KMS encryption context format", codes.ErrorInvalidKMSEncryptionContextFormat)
}
if c.String("kms") != "" {
for _, k := range kms.MasterKeysFromArnString(c.String("kms"), kmsEncryptionContext) {
for _, k := range kms.MasterKeysFromArnString(c.String("kms"), kmsEncryptionContext, c.String("aws-profile")) {
kmsKeys = append(kmsKeys, k)
}
}

View File

@@ -78,6 +78,7 @@ type kmsKey struct {
Arn string `yaml:"arn"`
Role string `yaml:"role,omitempty"`
Context map[string]*string `yaml:"context"`
AwsProfile string `yaml:"aws_profile"`
}
type azureKVKey struct {
@@ -90,6 +91,7 @@ type creationRule struct {
FilenameRegex string `yaml:"filename_regex"`
PathRegex string `yaml:"path_regex"`
KMS string
AwsProfile string `yaml:"aws_profile"`
PGP string
GCPKMS string `yaml:"gcp_kms"`
AzureKeyVault string `yaml:"azure_keyvault"`
@@ -175,7 +177,7 @@ func loadForFileFromBytes(confBytes []byte, filePath string, kmsEncryptionContex
for _, k := range pgp.MasterKeysFromFingerprintString(rule.PGP) {
keyGroup = append(keyGroup, k)
}
for _, k := range kms.MasterKeysFromArnString(rule.KMS, kmsEncryptionContext) {
for _, k := range kms.MasterKeysFromArnString(rule.KMS, kmsEncryptionContext, rule.AwsProfile) {
keyGroup = append(keyGroup, k)
}
for _, k := range gcpkms.MasterKeysFromResourceIDString(rule.GCPKMS) {

View File

@@ -44,6 +44,7 @@ func KeyFromMasterKey(mk keys.MasterKey) Key {
Arn: mk.Arn,
Role: mk.Role,
Context: ctx,
AwsProfile: mk.AwsProfile,
},
},
}

View File

@@ -243,6 +243,7 @@ type KmsKey struct {
Arn string `protobuf:"bytes,1,opt,name=arn" json:"arn,omitempty"`
Role string `protobuf:"bytes,2,opt,name=role" json:"role,omitempty"`
Context map[string]string `protobuf:"bytes,3,rep,name=context" json:"context,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
AwsProfile string `protobuf:"bytes,4,opt,name=aws_profile" json:"aws_profile,omitempty"`
}
func (m *KmsKey) Reset() { *m = KmsKey{} }

View File

@@ -37,6 +37,7 @@ func (ks *Server) encryptWithKms(key *KmsKey, plaintext []byte) ([]byte, error)
Arn: key.Arn,
Role: key.Role,
EncryptionContext: ctx,
AwsProfile: key.AwsProfile,
}
err := kmsKey.Encrypt(plaintext)
if err != nil {
@@ -85,6 +86,7 @@ func (ks *Server) decryptWithKms(key *KmsKey, ciphertext []byte) ([]byte, error)
Arn: key.Arn,
Role: key.Role,
EncryptionContext: ctx,
AwsProfile: key.AwsProfile,
}
kmsKey.EncryptedKey = string(ciphertext)
plaintext, err := kmsKey.Decrypt()

View File

@@ -42,6 +42,7 @@ type MasterKey struct {
EncryptedKey string
CreationDate time.Time
EncryptionContext map[string]*string
AwsProfile string
}
// EncryptedDataKey returns the encrypted data key this master key holds
@@ -131,7 +132,7 @@ func NewMasterKey(arn string, role string, context map[string]*string) *MasterKe
}
// NewMasterKeyFromArn takes an ARN string and returns a new MasterKey for that ARN
func NewMasterKeyFromArn(arn string, context map[string]*string) *MasterKey {
func NewMasterKeyFromArn(arn string, context map[string]*string, awsProfile string) *MasterKey {
k := &MasterKey{}
arn = strings.Replace(arn, " ", "", -1)
roleIndex := strings.Index(arn, "+arn:aws:iam::")
@@ -143,17 +144,18 @@ func NewMasterKeyFromArn(arn string, context map[string]*string) *MasterKey {
}
k.EncryptionContext = context
k.CreationDate = time.Now().UTC()
k.AwsProfile = awsProfile
return k
}
// MasterKeysFromArnString takes a comma separated list of AWS KMS ARNs and returns a slice of new MasterKeys for those ARNs
func MasterKeysFromArnString(arn string, context map[string]*string) []*MasterKey {
func MasterKeysFromArnString(arn string, context map[string]*string, awsProfile string) []*MasterKey {
var keys []*MasterKey
if arn == "" {
return keys
}
for _, s := range strings.Split(arn, ",") {
keys = append(keys, NewMasterKeyFromArn(s, context))
keys = append(keys, NewMasterKeyFromArn(s, context, awsProfile))
}
return keys
}
@@ -185,7 +187,7 @@ func (key MasterKey) createSession() (*session.Session, error) {
if matches == nil {
return nil, fmt.Errorf("No valid ARN found in %q", key.Arn)
}
config := aws.Config{Region: aws.String(matches[1])}
config := aws.Config{Region: aws.String(matches[1]), Credentials: credentials.NewSharedCredentials("", key.AwsProfile)}
opts := session.Options{
Config: config,
AssumeRoleTokenProvider: stscreds.StdinTokenProvider,

View File

@@ -48,7 +48,7 @@ func TestKMS(t *testing.T) {
func TestKMSKeySourceFromString(t *testing.T) {
s := "arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e+arn:aws:iam::927034868273:role/sops-dev, arn:aws:kms:ap-southeast-1:656532927350:key/9006a8aa-0fa6-4c14-930e-a2dfb916de1d"
ks := MasterKeysFromArnString(s, nil)
ks := MasterKeysFromArnString(s, nil, "foo")
k1 := ks[0]
k2 := ks[1]
expectedArn1 := "arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e"

View File

@@ -67,6 +67,7 @@ type kmskey struct {
Context map[string]*string `yaml:"context,omitempty" json:"context,omitempty"`
CreatedAt string `yaml:"created_at" json:"created_at"`
EncryptedDataKey string `yaml:"enc" json:"enc"`
AwsProfile string `yaml:"aws_profile" json:"aws_profile"`
}
type gcpkmskey struct {
@@ -135,6 +136,7 @@ func kmsKeysFromGroup(group sops.KeyGroup) (keys []kmskey) {
EncryptedDataKey: key.EncryptedKey,
Context: key.EncryptionContext,
Role: key.Role,
AwsProfile: key.AwsProfile,
})
}
}
@@ -265,6 +267,7 @@ func (kmsKey *kmskey) toInternal() (*kms.MasterKey, error) {
EncryptedKey: kmsKey.EncryptedDataKey,
CreationDate: creationDate,
Arn: kmsKey.Arn,
AwsProfile: kmsKey.AwsProfile,
}, nil
}