-
Notifications
You must be signed in to change notification settings - Fork 480
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
Enhance AWS node attestor server plugin to validate EC2 instances across multiple AWS account. #2218
Comments
One potential solution for this problem could be to allow providing a role name as part of AWS aws_iid node attestor plugin configuration. The spire server will perform AssumeRole in the AWS account presented by the AWS aws_iid document. It is assumed that same role name is present in all AWS accounts. If no role name is provided as part of plugin configuration, the spire server will continue with the current implementation. |
If we limit the selectors to be based on the fields of the IID and since we are able to verify the IID document through AWS DSA public certificate, wonder if we can get away from the need for AWS specific credentials on the SPIRE server. |
I like @walmav's idea. It will make the workflow similar to the one implemented in the Looking into the docs I see there are 3 types of signatures available. |
I was digging into the AWS IID. When I run I do not see any suitable fields in this that can use be used to form selectors. That could be the reason that the current implementation of AWS node attestor is making call to AWS API to acquire additional information about the EC2 instance and then converting it to a set of node selectors. It may be that going back to AWS API is unavoidable. |
I love this. It is much better than having to provide creds for multiple accounts :) Is role assumption required to do this? Or is it also possible for other AWS accounts to grant access to us directly based on the ARN of our role in this account? I also wonder if anything funny can happen here... someone with an IID from a totally random account can make SPIRE Server try to assume a role in it. I don't know if that's bad or not... it's probably worth thinking about for a while
Hmm I think this could work OK from a compat standpoint, but this plugin has a lot of other work that needs to be done, and I'd really love to get the configuration experience refactored as a whole.
As @sushil-prasad has pointed out, the information contained in the IID itself is of limited value. I don't know if there are use cases for AWS validation that involve the AWS APIs being unreachable, but I think an option to disable AWS API calls is reasonable, so long as the user understands that they'll get only limited information back as a result.
Yes, we might ned an account allowed list no matter what direction we take here.
Hmm good question, I don't know... I think this has changed slightly since the last time I looked (e.g. the key to verify the signature is no longer publicly available...) |
Just chiming in here +1 on having an I am seeing that in 12.2 however it is forcing me to use an InstanceProfile in which for my shop the way we configure our EKS clusters, we have a single InstanceProfile for each node.group. We actually do not use the InstanceProfiles, but for some reason their attached to our instances. So actually allowing a cluster InstanceProfile to run the queries needed to get aws_iid to attest seems problematic because we really dont want the entire cluster the ability to describe and get metadata. |
Hey @caleygoff-invitae thanks for adding this, it is good to know. I thought that the ability to assume a role was based on some role you already have (i.e. instance profile role)? Or there is some other way to specify who is authorized to assume? |
My understanding is we can do both, either by specifying a Role ARN to assume via the STS Assume Role API by passing in the ARN https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials/stscreds/ Or use the Ec2 instance profile that we're already doing https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials/ But yes in both cases the role already exists and is setup we are just passing in the IAM role arn for the specific workload to use in one use case and applying an the IAM role arn to an instanceprofile and associating that to an ec2 for all workloads in another case. It should also be noted that on the IAM Role thats passed into the workload there is a trust relationship and sts:AssumeRole is allowed on the ARN in which the workload is running (our cluster node.group arn) . I just realized that the |
👍 |
I think the singular |
Yes, ok .. this is all helpful, thanks everone. IMO the right thing to do here is probably user configurable role name. We try to assume the role you specify in the account presented by the IID. My relatively strong preference is to avoid an account/role map if at all possible. While it is certainly more flexible, it's also more of a pain to configure, you need to know these ARNs, and if the name is the same you can't just set it once and go.
Yes... I agree, and FWIW, I do think we also need an allow list. Just to double-check, nobody here is concerned about the following?
|
I'm like 90% sure this only an issue if the accounts in question have allowed the other to be assumed. Otherwise AWS just denies the request and would never allow an arbitrary account ARN to assume a role belonging to some other arbitrary account ARN. At least in my experience I have had to explicitly setup policies and trust entities to allow for cross account assumerole access on a given role. |
When considering this, my mind goes to places like:
|
Hey @sushil-prasad, curious to hear if you have any thoughts on the above? Also, is this functionality something you'd be willing to contribute? |
I would love to contribute towards this. Please assign this ticket to me. Let me review the code and test all the assumptions and then I will propose the potential design and draft PR. As long as the rate limit is concerned, I think doing this per IP might be simpler than per AWS account. I have seen similar issues in other scenarios happening with the same AWS account itself. Finding the right volume per account might be tricker based on account size. Finalizing the upper bound on the rate limit per IP is much easier. Any suggestion on what the rate limit per IP should be (10 requests/per minute???). Should this limit be configurable? Should we allow a configurable DENY account list? I agree with @caleygoff-invitae. This will need explicit policies and trust entities. I will also document the exact AWS policy needed to make this work. This will also help us review if this change accidentally introduces any potential security vulnerabilities. |
Maybe a silly question from my side, but is there a way to get rid of the need for pre-shared Similar to what is the configuration experience of the gcp_iit. Just require secrets when you actually need more sophisticated selectors than the one available in the Of course this should not be at the cost of any major security implications. P.S. I'm commenting here, because I think those two are very much related, but feel free to ask me to follow-up in another issue if you don't see it fit here |
@georgi-lozev I think access_key_id and secret_access_key are optional configuration. If you do not specify them, spire server falls back to using EC2 security group. In our deployment, we have granted required permissions to the security group that is attached to the spire server and we do not configure access_key_id/secret_access_key |
Hmm, that's interesting @sushil-prasad Based on my experiments where I've used different accounts for the SPIRE server and the workloads I didn't managed to make this call
It could be that I have misconfigured something or was somehow mislead from the docs, so I didn't spent too much time trying to make it working without credentials. |
@georgi-lozev For my case, both spire-server and spire agents are running in the same AWS account. The current code will not work across multiple account without explicit AWS credentials. Going across accounts without explicit AWS credentials with need Assume Role which is this enhancement is trying to address |
Here is the doc describing delegate access across AWS accounts using IAM roles The spire agent account MUST be recognized by the spire server account to make the spire server issue the certificate. So sending the AWS IID from a random account to the spire server will fail at DescribeInstance step in the spire server and hence no certificate will be issued. Here is the high level setup to make this work:
Setup
From a security perspective, a Spire server account has no control over a spire-agent account. But the spire server account has control over this step. So sending an AWS IID from a random account will fail because the spire server will not be able to assume spire-delegate-role@spire-agent-account in the random spire-agent-account. Hence no certificate will be issued. |
On the rate limits: I am assuming that the spire server is not exposed on the public network. So we are talking about spire servers and agents taking over private networking. This will require explicit network configurations between AWS accounts like VPC peering. This means that only configured AWS spire agent accounts are able to talk to Spire server. That leaves us to the case, where an EC2 host is compromised and it is being used to abuse the spire server. This possibility exists even when spire-server is serving just one or few pre configured AWS accounts. So my opinion is that we should externalize the hardening of the spire server deployment and keep the spire code simple. The rate limit could be implemented in the load balancer layer or using iptables (if this has to be done on the spire server hosts). https://making.pusher.com/per-ip-rate-limiting-with-iptables My goal here is to get to a point where just adding Assume Role in the AWS Node Attestor plugin is sufficient without introducing additional security vulnerabilities (or have an known option to address them externally). I will start working on this issue accordingly. |
PR: #2387 |
…2387) If assume_role_arn_template parameter is set in the AWS server node Attestor plugin, the spire server will assume the role as specified by the assume_role_arn_template after expanding the template. Currently only template variable available is AccountID from the AWS IID document sent by the spire agent to the spire server. * added assume_role_arn_template parameter to AWS server node attestation plugin * return grpc status on error * changed parameter assume_role_arn_template to assume_role in AWS server node attestor plugin configuration Signed-off-by: Sushil Prasad <[email protected]>
#2387 is now merged, @sushil-prasad is this issue fixed? |
Thanks a lot for merging this. I will test this and update this PR. |
@evan2645 The change on the main worked. We can close this issue. |
Awesome, thanks for the confirmation @sushil-prasad |
…2218) (spiffe#2387) If assume_role_arn_template parameter is set in the AWS server node Attestor plugin, the spire server will assume the role as specified by the assume_role_arn_template after expanding the template. Currently only template variable available is AccountID from the AWS IID document sent by the spire agent to the spire server. * added assume_role_arn_template parameter to AWS server node attestation plugin * return grpc status on error * changed parameter assume_role_arn_template to assume_role in AWS server node attestor plugin configuration Signed-off-by: Sushil Prasad <[email protected]>
…2387) If assume_role_arn_template parameter is set in the AWS server node Attestor plugin, the spire server will assume the role as specified by the assume_role_arn_template after expanding the template. Currently only template variable available is AccountID from the AWS IID document sent by the spire agent to the spire server. * added assume_role_arn_template parameter to AWS server node attestation plugin * return grpc status on error * changed parameter assume_role_arn_template to assume_role in AWS server node attestor plugin configuration Signed-off-by: Sushil Prasad <[email protected]>
We are trying to set up the spire infrastructure in our production environment. The production environment has multiple AWS accounts. We want to deploy a spire server in one of the accounts and attest the EC2 hosts in all other AWS accounts using AWS aws_iid node attestor.
When both the spire server and the spire agent runs in the same AWS account, the spire server is able to attest to the EC2 host. However when spire server and spire agent are in different AWS account, the node attestation fails with this message:
ERRO[0000] agent crashed error=“failed to get SVID: error getting attestation response from SPIRE server: rpc error: code = Internal desc = failed to attest: rpc error: code = Unknown desc = aws-iid: attempted attestation but an error occurred querying AWS via describe-instances: InvalidInstanceID.NotFound:
The text was updated successfully, but these errors were encountered: