ACM.84 Granting an IAM Group permission to make use of a KMS key in a Key Coverage
This can be a continuation of my sequence of posts on Automating Cybersecurity Metrics.
We’ve been engaged on including a user-specific secret in Secrets and techniques Supervisor prior to now few posts and regarded how you can deploy secrets and techniques in a way that helps non-repudiation.
- Creating and Storing an EC2 SSH Key in Secrets and techniques Supervisor
- Consumer-Particular Secrets and techniques on AWS: IAM Insurance policies
- Consumer-Particular Secrets and techniques on AWS: Separation of Duties
The issue we’ve from the primary put up is that we modified our KMS coverage to permit the Builders Group Function to make use of the KMS key. Though our person (Developer) and describe the important thing, the person can’t get the important thing as a result of that IAM person doesn’t have permission within the KMS Key coverage to make use of the key.
Modifying our KMS Key Coverage to assist a number of customers
Right here’s our subsequent problem. Our KMS key script that we’ve been utilizing up until now expects one enter for a decrypt person. We have to enable a number of customers to make use of the important thing to decrypt their very own secrets and techniques based mostly on the design within the final two posts. I defined that we’re not utilizing a per-user key because of the price in a previous put up, however you would use that choice in a high-security surroundings.
We will repair this concern by altering our key coverage to absorb a listing as a substitute of a single ARN. As well as we will loop via our customers in our Group and add them to the coverage, much like how we added customers in a Group to a belief coverage as described on this put up:
Assigning a Group to a Belief Coverage in an AWS IAM Function
Basically we need to enable a Group to make use of a KMS key however AWS coverage paperwork don’t assist teams as principals so we’ve to loop via the customers of the group and add every one to the important thing coverage.
For starters, I need to attempt one thing I didn’t attempt for the position coverage within the above put up. I need to use the present KMS template however cross in a listing. I can merely change the sort for my encrypt and decrypt ARN to a CommaSeparatedList
There’s one other factor I would like to vary. Since we at the moment are passing in a listing as a substitute of a single worth, I have to take away the sprint under.
Modifying coverage statements to assist a comma separated listing
We have to take away the encrypt and decrypt ARNs from the describe key assertion since we have been individually itemizing and referencing three separate roles. I presume we will’t cross in two lists, although we may attempt. It’s in all probability simply simpler so as to add DescribeKey permission to our encrypt and decrypt statements and take away these two single values from the describe key assertion.
Once I tried this out, no luck. It appeared as if KMS key insurance policies don’t work the identical approach {that a} belief coverage does. Upon additional testing, it turned out to be another as of but nonetheless unknown concern I didn’t care to pin down. It might even be good if this error message pinpointed the road in error within the coverage doc.
To confirm this downside was not only a typo (which I suppose it was) I restored the important thing coverage to what I believed it was within the first place from an area backup however I nonetheless received the above error. Hmm. So I pulled my code again out of supply management that I do know works. It up to date efficiently.
Another attempt to modify the KMS coverage to verify it wasn’t only a typo.
To be additional cautious, I up to date and examined the coverage adjustments one by one. I eliminated the encrypt ARN from the describe key coverage and eliminated the sprint in entrance of the encrypt ARN within the associated coverage since it’s now a listing. That labored!
OK now do the identical for the decrypt ARN.
That additionally labored. Subsequent copy and paste the DescribeKey permission to the statements for encrypt and decrypt.
That works additionally. So I should have had some additional house someplace as a result of that’s precisely what I believed I simply did. AWS Coverage Paperwork and lack of useful error messages are one of many trickiest issues to get proper on AWS.
So right here’s what we’ve to this point. Encrypt and Decrypt ARN parameters at the moment are a comma delimited listing:
The describe key coverage assertion solely has the basis person:
The encrypt assertion references the encrypt ARN parameter with no sprint and the assertion has the DescribeKey permission now:
Identical for the Decrypt assertion:
Now, to this point I used to be simply testing my present deploy script as is. I haven’t gotten the listing of customers from the group to cross in. If we need to enable the KMS person to do this we’ll want so as to add the GetGroup permission to the KMS group position. Add this permission and deploy the position.
Subsequent we’d like away to get the listing of customers to cross in because the encrypt and decrypt ARN.
We will reuse the code we used earlier than to get a comma separated listing of IAM customers. Now I discover that I forgot so as to add a profile so I’ll add that now. As well as we at the moment are utilizing this code in two locations so I’ll transfer it to the shared features file.
Subsequent we have to get the listing of customers through our new perform and cross it in to create the important thing coverage utilizing that listing.
At this level I get the next error. This error is deceptive and isn’t precisely the issue, although the error is said to parameters:
An error occurred (ValidationError) when calling the CreateChangeSet operation: Parameter 'ServiceParam' have to be certainly one of AllowedValues
Having a look on the parameters. They don’t look appropriate in any respect so I’ve a typo someplace.
I had set the service to “secretsmanager”.
…however that’s not what’s listed under. It’s utilizing the primary phrase of the outline because the service parameter and the second phrase as the outline parameter. So clearly I didn’t set one of many parameters appropriately if in any respect. It’s lacking so single phrases from the outline are getting pulled up into different values (all a part of the problems with spacing an bash perform parameters when utilizing the AWS CLI I’ve written about earlier than…)
What are the CloudFormation template parameters?
DecryptArn in my above parameters is just not an ARN or a listing of ARNs. So initially, this isn’t working:
To check this perform independently I created a take a look at.sh file and as soon as I began shifting the code over to check it I spotted that I by no means set the group variable. Oops.
After setting that variable so the group will get handed into the CloudFormation template, now my parameters look appropriate.
And, that labored.
Be good to individuals who use your code — and your self!
However what was the true downside with my code? I forgot so as to add the verify for lacking parameters in my get_users perform to offer me a pleasant error message that clearly signifies the issue. Head on over to our perform and add the lacking checks.
Subsequent I re-tested the important thing deploy.sh script to verify I didn’t introduce an error.
Now we head over to the important thing alias deploy script and add code to deploy an alias and take a look at it:
That works:
OK now we will take a look at for those who our person can get the key from secrets and techniques supervisor.
get-secret-value – AWS CLI 2.8.2 Command Reference
Recall that we created a profile for our developer in a previous put up.
aws secretsmanager get-secret-value --secret-id Developer --profile developeruser
Entry to KMS is just not allowed.
An error occurred (AccessDeniedException) when calling the GetSecretValue operation: Entry to KMS is just not allowed
Issues with our key coverage circumstances
What are we lacking? This can be a irritating error message as a result of it doesn’t inform us if the issue is within the IAM or the KMS coverage. Once I assessment them they each seem to have permissions for KMS and our key. Let’s head over to CloudTrail. Ah, however as soon as once more the circumstances coverage doesn’t appear to be appropriate. Once I created the important thing I handed in secrets and techniques supervisor because the service, however it doesn’t have secrets and techniques supervisor within the situation. It might be good if the error message from AWS talked about the situation particularly and supplied a extra correct error message (#awswishlist).
To be completely trustworthy, I mounted this code as soon as earlier than however after I went again to take a look at the code, my adjustments have been lacking. So I get to “follow” fixing this error once more.
Again to CloudFormation to validate that secretsmanager was handed in for the service. My parameter is appropriate however this logic is inaccurate. Do you see the downside?
Ought to say ServiceIsSecretsManager. I based mostly my subsequent logic on the identify so want to repair that as effectively by swapping the order in my Fn::If statements. And naturally after due that I get an error a couple of typo.
Now I’ve to redeploy all my keys that have been utilizing that incorrect template. Because of this having a take a look at surroundings and take a look at scripts is so necessary earlier than pushing adjustments to manufacturing.
And now…my developer person can retrieve their very own secret from secrets and techniques supervisor.
MFA revisited
Recall that two posts in the past we couldn’t add MFA to our user-specific secrets and techniques coverage. Let’s revisit all of the actions our person simply took and see if MFA exists for any of them. I needed to wait a bit for the knowledge to indicate up in CloudTrail however when it did I get the next listing of actions for the above command. Additionally attention-grabbing that KMS doesn’t present what’s being decrypted — on this case a Secrets and techniques Supervisor Secret. That might be good.
Let’s see if MFA is present in both of the above. Right here’s the place issues get attention-grabbing.
GetSecretValue has no MFA flag.
The KMS request does, however it’s set to false.
The odd factor is that I’m nonetheless implementing MFA with a boolean in my AWS IAM Consumer secret coverage:
So apparently:
- Including MFA for a person within the CLI configuration does nothing (which I sort of already coated earlier than).
- Including a situation to implement MFA for kms:Encrypt and kms:Decrypt in an IAM coverage does nothing if a person for IAM person programmatic entry? Is {that a} bug? Or am I lacking one thing…
There are two potential methods we may resolve this downside to implement MFA — and I say potential as a result of certainly one of them depends on the above situation that doesn’t appear to be working. You’d want to check this out to know for positive:
- Enable the person to imagine a user-specific position which requires MFA for position assumption. Change all of our code to permit every user-specific position to entry it’s personal secret.
- Solely enable the customers to acquire their secrets and techniques from the AWS Console, wherein case MFA may be enforced to log into the console.
Neither one sounds extraordinarily interesting to me in the mean time, however let’s say we did need to enable console-only entry to acquire the key. We would want to offer the person console entry when created (replace the person template and deploy script to incorporate these choices). We’d want a approach to implement entry to the key solely through the AWS Console.
The one doable approach I see to do this is through the person agent within the request and anybody who’s ever carried out penetration testing 101 is aware of that’s tremendous simple to bypass. I may submit a programmatic request and alter the user-agent in flight on it’s approach to the service (after it leaves the CLI or every other software I’m utilizing).
Alright. So we’re again to making a user-specific position. And now this all looks like a bit a lot as a hacky workaround. Nicely, we should always have a user-specific secret. We simply can’t implement MFA simply. Possibly I’ll revisit this later.
IP Restrictions
There’s one different situation we may add. We may prohibit the coverage to a particular IP tackle or IP vary. For those who use the Developer Bastion Host concept in a previous put up, you would lock down the IP to the person’s VM IP tackle inside your VPC. The issue with that’s that IP addresses are ephemeral and alter. If we enable entry to a single IP tackle and the developer restarts their VM (EC2 occasion) then the IP tackle will change and the developer wouldn’t have the ability to entry their secret.
Moreover, the VM I’m utilizing is presently reporting the general public IP within the request. If the IP adjustments it might grant entry to an IP utterly unrelated to our account, although the individual wouldn’t have entry because of IAM permissions. There are restrictions on elastic IP addresses — you may solely get so many, so it could be troublesome to lock down a particular secret to a particular IP tackle.
Nonetheless, if we begin utilizing a VPC endpoint, we may even see that our request comes via at a personal IP tackle belonging to our developer VPC. In that case, we will prohibit entry to our Developer VPC and the Developer VMs deployed it it. This may not stop builders inside your group from accessing secrets and techniques based mostly on IPs however it could stop stolen developer credentials or periods from getting used to entry developer secrets and techniques exterior your developer VPC.
Let’s say somebody by chance despatched logs to AWS assist as defined on this put up:
There’s a rogue insider at AWS who tries to make use of that session to get entry to developer secrets and techniques. We lock down deployment of EC2 cases and different compute sources so that’s solely doable with MFA. In that case, the session credentials couldn’t create a useful resource in your account to run the code from the VPC with an allowed IP tackle. An exterior request ought to have a public IP. So even with a legitimate session, the credentials couldn’t be used to entry the secret.
AWS Credentials in Boto3 and CLI Debug Output
I’m speculating right here. We don’t know for positive till we check it out. That is an instance of how weaknesses in a single facet of your safety controls may be offset by different safety controls. Designing safety controls may be tough, relying on how safe you need to be!
I all the time attempt to maintain it so simple as doable, and in my thoughts the only factor for me could be if AWS would repair the aforementioned points that received us so far. For now, I’m going to depart what we’ve in place and presumably revisit it later. Possibly I’ll give you a greater concept. 🙂
Testing different profiles CANNOT entry the secret
Everytime you take a look at code and particularly code associated to IAM insurance policies, don’t simply take a look at that it really works. Phew. Carried out.
Check that the issues that shouldn’t work don’t.
What occurs if we swap to our IAM Profile:
How about our KMS profile? Identical factor.
So presuming the KMS person and IAM person would not have permission to change the useful resource coverage (which isn’t true in our present implementation for the IAM person however I defined how you can repair it within the final put up), then solely the Developer that owns the important thing ought to have the ability to retrieve it and use it to login to EC2 cases with that SSH key assigned.
If we create a per-user EC2 occasion, we will lock down the occasion and key to a particular person.
What if the safety crew must entry that occasion? There’s a approach to change the SSH key for an EC2 occasion in case of a safety emergency. Additionally, you will need to perceive who can do that and make sure that individuals who shouldn’t be doing this are not:
Reset passwords and SSH keys on EC2 cases
We nonetheless have work to do:
- We don’t actually have non-repudiation. We’ll have to assume via the structure of our IAM insurance policies a bit extra.
- I ultimately opted to offer Builders console entry because of limitations with roles and developer keys associated to MFA and user-specific permissions. For that we needed to replace the developer and assume via how we’re handing out credentials. Extra points with non-repudiation.
- I discovered some points with this implementation after I lastly received via all that so I may take a look at person entry within the console. Take a look at Half 4 which comes after resolving a few of the above in posts in between.
Observe for updates.
Teri Radichel
For those who appreciated this story please clap and comply with:
Medium: Teri Radichel or E-mail Record: Teri Radichel
Twitter: @teriradichel or @2ndSightLab
Requests companies through LinkedIn: Teri Radichel or IANS Analysis
© 2nd Sight Lab 2022
All of the posts on this sequence:
Automating Cybersecurity Metrics (ACM)
____________________________________________
Creator:
Cybersecurity for Executives within the Age of Cloud on Amazon
Want Cloud Safety Coaching? 2nd Sight Lab Cloud Safety Coaching
Is your cloud safe? Rent 2nd Sight Lab for a penetration take a look at or safety evaluation.
Have a Cybersecurity or Cloud Safety Query? Ask Teri Radichel by scheduling a name with IANS Analysis.
Cybersecurity & Cloud Safety Assets by Teri Radichel: Cybersecurity and Cloud safety lessons, articles, white papers, shows, and podcasts
Consumer-Particular Secrets and techniques on AWS: KMS was initially revealed in Cloud Safety on Medium, the place persons are persevering with the dialog by highlighting and responding to this story.