Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to encrypt a file locally with an assumed KMS role and decrypt it AWS without any role #555

Open
zioalex opened this issue Oct 25, 2019 · 7 comments

Comments

@zioalex
Copy link

zioalex commented Oct 25, 2019

Problem description:

I am going to use Sops in Aws EKS. The current workflow presume that the developer will encrypt a secret assuming a special role. Later, such encrypted file, is used in AWS and needs to be decrypted without such role ( The AWS node has the proper access to do it )
Follow my .sops.yaml file

 creation_rules:
   - key_groups:
     - kms:
       - arn: "arn:aws:kms:us-east-1::XXXXXXXXXXXXX:key/kms_key_id"
         role: "arn:aws:iam::XXXXXXXXXXXXX:role/EncryptionRole"
     - kms:
       - arn: "arn:aws:kms:us-east-1:XXXXXXXXXXXXX:key/kms_key_id"

With the above config the encryption process will fail because the user cannot use the 2 key directly, even though is the same.
My current workaround is to comment the last 2 lines from the .sops.yaml, encrypt the file, and remove the "role:" line from the encrypted file.
In this way I can decrypt the key in AWS.

Ideas

Have the possibility to specify which key to use to decrypt
Rewrite the encrypted the file with the specified arn independently from the one used for encryption
Other ideas are welcome.

@autrilla
Copy link
Contributor

Have the possibility to specify which key to use to decrypt

SOPS will try all keys, so it doesn't really matter whether you specify them or not (other than for cost savings for KMS API requests).

In your case, I would give whoever has access to the first key Encrypt access (but not Decrypt access) through AWS IAM. Is there any reason you can't do that? In the current model, whoever creates the file needs encryption access to all keys, and changing that wouldn't be easy.

You could alternatively create the file with key 1, and whoever has access to key 2 can then use sops updatekeys to add their own key. But they'd need access to both key 1 and key 2.

@zioalex
Copy link
Author

zioalex commented Oct 28, 2019

I do not think your proposal would work in our case.
Let me clarify better our user case.
Somebody will encrypt from a local laptop using the arn:aws:kms:us-east-1::XXXXXXXXXXXXX:key/kms_key_id and the role arn:aws:iam::XXXXXXXXXXXXX:role/EncryptionRole and push this to a repo that will be used later from our CD pipeline; the user cannot access the key directly. He needs to assume the role.

We have our EKS cluster running in AWS. The nodes in AWS are running with a different Role and this role has already the capability to decrypt using the key arn:aws:kms:us-east-1::XXXXXXXXXXXXX:key/kms_key_id . So in this case no other IAM config is needed.

Now we the above .sops.yaml configuration sops will fail because the user assure cannot use the key directly.
To solve it I commented the last 2 lines in the .sops.yaml file and the encrypted file looks like:

secret: ENC[AES256_GCM,data:ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ==,type:str]
sops:
    shamir_threshold: 2
    key_groups:
    -   pgp:
        -   created_at: '2019-10-28T11:01:54Z'
            enc: |
                -----BEGIN PGP MESSAGE-----
                ....
                =SVyI
                -----END PGP MESSAGE-----
            fp: WWWWWWWWWWWWWWWWWW
    -   kms:
        -   arn: arn:aws:kms:us-east-1::XXXXXXXXXXXXX:key/kms_key_id
            role: arn:aws:iam::XXXXXXXXXXXXX:role/EncryptionRole
            created_at: '2019-10-28T11:01:54Z'
            enc: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
            aws_profile: ""
    kms: []
    gcp_kms: []
    azure_kv: []
    lastmodified: '2019-10-28T11:02:18Z'
    mac: ENC[AES256_GCM,data:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx,type:str]
    pgp: []
    unencrypted_suffix: _unencrypted
    version: 3.4.0

Now in our pipeline this will fail because sops will try to assume the role specified arn:aws:iam::XXXXXXXXXXXXX:role/EncryptionRole . To solve it I just removed the role line and sops is able to decrypt the secret as expected.
I hope that now it is clearer.

@ahawkins
Copy link

ahawkins commented Jul 3, 2020

@ajvb I have the same issue. I need to use an IAM role when encrypting/decrypting on my local machine, then forego the IAM role during the CD pipeline. The IAM role for the CD pipeline grants access to the KMS key. I came up with a similar solution. I parse the YAML file and drop the role entry. Luckily this work.

What do you think of this use case? It seems reasonable to assume that humans will need roles and that machines may not (given they're authorized by AWS instance profiles or similar).

ahawkins added a commit to ahawkins/terraform-provider-sops that referenced this issue Aug 21, 2020
REF: getsops/sops#555

Remove "role" references from content before passing to the sops
library.

Activate the feature by exporting SOPS_SKIP_KMS_ASSUME_ROLE=1
@eddycharly
Copy link

I currently face the same issue, is there a proper solution for this ?

@parkwart
Copy link

parkwart commented Apr 1, 2021

#650 (comment) seems familiar and led me to this solution:

  1. delete aws cli credentals ~/aws/credentials, to start over fresh
  2. login into account A via cli
  3. change credentials file from profile "default" to "myfirstaccount"
  4. login into account B via cli (should now be the default profile, "myfirstaccount" with credentials should still be there)
  5. encrypt your file with "sops -e -i -k KMS_ARN_FROM_ACCOUNT_B YOUR_FILE
  6. add key from account A with "sops -r -i --add-kms KMS_ARN_FROM_ACCOUNT_A --aws-profile "myfirstaccount YOUR_FILE"
  7. change in YOUR_FILE "sops_kms___list_x__map_aws_profile=myfirstaccount" to "sops_kms___list_x__map_aws_profile="

--> decrypting in both accounts or ec2 in one of the accounts, without any specific role (as long it's able to use the key) works just fine

@autrilla actually i'd expect that "tampering" with the final encrypted file would result in a way that sops can't decrypt it anymore 🤔

@klemmster
Copy link

Thanks parkwart.

This even works with multiple accounts, but only if the aws_profile setting is filled. If you try to encrypt with one empty, not logged in profile, you'll end up with an empty file again.

@thuandt
Copy link

thuandt commented Sep 5, 2021

I have similar issue with EKS, IRSA and ksops.

In my setup, I want to avoid using static AWS access keys, then I created 2 roles:

  1. IRSA role for ArgoCD: RoleA
  2. sops role for developers to encrypt/decrypt secrets RoleB

On EKS cluster:

  • ArgoCD assumed to RoleA (sts:AssumeRoleWithWebIdentity) then running ksops to decrypt data.

  • ksops must assumed to RoleB to decrypt data (follow yaml file), but STS session name is unique, I can't add it as trusted relationship on RoleB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants