I have a service account that's being used in a pipeline for Terraform. Currently, it has the owner role, but I want to restrict what roles it can assign via the Terraform configuration. I want to avoid a scenario where a user can elevate their role to the owner role and bypass the pipeline. This also includes the users who are responsible for reviewing and approving.
I'm following this guide but it shows assigning a role that ONLY assigns roles, I need to deploy resources as well. https://cloud.google.com/iam/docs/setting-limits-on-granting-roles#use-cases
{
"members": [
"finn#example.com"
],
"role": "roles/resourcemanager.projectIamAdmin",
"condition": {
"title": "only_billing_roles",
"description": "Only allows changes to role bindings for billing accounts",
"expression":
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/billing.admin', 'roles/billing.user'])"
}
}
Is there a way to specify the owner role on the service account but then limit what roles it can assign and what resources it can deploy?
Related
I have a few SSO permission sets defined for the users in my system.
These are connected to IAM roles where it's defined which policies are attached to each role.
Is it possible to see the connection between an SSO permission set and the connected role?
If so where? Can this information be accessed via AWS CLI?
From AWS documentation:
Permission sets are stored in AWS SSO and are only used for AWS
accounts. They are not used to manage access to cloud applications.
Permission sets ultimately get created as IAM roles in a given AWS account, with trust policies that allow users to assume the role
through AWS SSO.
If I understand correctly: when an SSO permission set is created, this permission set generates an IAM role automatically. When the permission set is updated, it also updates the connected IAM role. The name of the role matches the name of the SSO permission set with "AWSReservedSSO_" in front of the role name.
Is it possible to see which permission set is responsible for which role or is the name the only clue to this connection?
Maybe AWS will add expand this capability for tagging aws permissions sets and propagating them to the provisioned roles in the destination accounts but as of now, it is not supported.
Tagging AWS Single Sign-On resources
Currently, tags can only be applied to permission sets and cannot be applied to corresponding roles that AWS SSO creates in AWS accounts
There are two other ways I can think right now, one I use myself(roles descriptions)
I assume most of the time we endup adding a canned policy for permissions set like arn:aws:iam::aws:policy/job-function/NetworkAdministrator etc.
We can do describe permissions on the role in question and this will give us the more confidence for the permissions set to sso role
$ aws iam list-attached-role-policies --role-name AWSReservedSSO_NetworkAdminAccess_abcdec
{
"AttachedPolicies": [
{
"PolicyName": "AmazonVPCCrossAccountNetworkInterfaceOperations",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonVPCCrossAccountNetworkInterfaceOperations"
},
{
"PolicyName": "NetworkAdministrator",
"PolicyArn": "arn:aws:iam::aws:policy/job-function/NetworkAdministrator"
}
]
}
option we can consider, when we don't use the canned policy like above, we created our own iam policy and attached to the permissions set. In that case we have Description field available for us and we can have the necessary information in there. For example:
$ aws iam get-role --role-name AWSReservedSSO_ViewOnlyAccess_Support_bacdefasdasd
{
"Role": {
"Path": "/aws-reserved/sso.amazonaws.com/eu-central-1/",
"RoleName": "AWSReservedSSO_ViewOnlyAccess_Support_fsdfsdfds",
"RoleId": "dhjdhdhddadasd",
"Arn": "sso role arn",
"AssumeRolePolicyDocument": {}
"Description": "ViewOnlyAccess + allowed to create support tickets",
"RoleLastUsed": {}
}
}
I couldn't understand the use of IAM Passrole. Can anyone explain with simple example?
I am referring the page : https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html but couldn't make much sense out it.
PassRole is a permission granted to IAM Users and resources that permits them to use an IAM Role.
For example, imagine that there is an IAM Role called Administrators. This role has powerful permissions that should not be given to most users.
Next, imagine an IAM User who has permissions to launch an Amazon EC2 instance. While launching the instance, the user can specify an IAM Role to associate with the instance. If the user — who is not an Administrator — were to launch an EC2 instance with the Administrators role, then they could login to the instance and issue commands using permissions from that role. It would be a way for them to circumvent permissions: while not being an administrator themselves, they could assign the IAM Role to a resource, and then use that resource to gain privileged access.
To prevent this scenario, IAM requires that the user be granted the iam:PassRole permission for the Administrators role. If the user does not have that permission, then they will not be permitted to launch the EC2 instance as described, or to assign that role to any other services. It gives them permission to pass a role to a service or resource.
Simply,
when the service B needs the ROLE
A has the iam:PassRole permission about the ROLE,
A can give the ROLE to B.
This is the permission granted for a user to be allowed to pass a role to a service during configuration, without this a user can not perform that binding. You can use this permission combined with resource Arns to limit what roles the user can pass to the service
If for example you have many applications with many different available IAM roles to choose from you might want to restrict the roles a user is able to pass to the service. You would be able to limit this scope using the below statements.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:PassRole"
],
"Resource": [
"arn:aws:iam::<account-id>:role/EC2-WordpressRole",
"arn:aws:iam::<account-id>:role/EC2-DatabaseRole"
]
}]
}
In the above scenario there might also be a arn:aws:iam::<account-id>:role/EC2-AdminRole but because this role grants an EC2 host permissions this user should not be able to give to an EC2 it is withheld from the EC2 list by the person who configured the permissions.
I have two AWS accounts: an account that holds my secrets, an account for deployment of my cloudformation stack. I am using cloudformation to deploy my infrastructure as code and have a pretty simple CD pipeline:
deploy to my dev stack
wait for approval
destroy the dev stack
deploy to my production stack
EC2 instances created as part of my stack rely on the secrets during start up. I would like to add the secret ARNs to my EC2 userdata script then use the AWS command line to retrieve the secret value when the userdata script is executed.
The IAM service roles used by my EC2 instances are also created as part of my cloudformation script. As such, the IAM role ARNs are not known prior to the launch of the stack. I find myself in a bit of a catch-22: I cannot launch my stack until access is granted to my secrets, but I cannot grant access to my secrets because the Principal in the resource policy does not accept wildcards.
Does anybody know how I might be able to create a secretsmanager resource policy for my secrets which does not require the IAM role ARN to be known beforehand? Or perhaps any other ideas?
What may be a better alternative to specifying the principals in the resource policy is to use Attribute Based Access Control (ABAC, a.k.a tagging). There is a fairly detailed tutorial on setting this up for IAM policies which can be modified for resource policies.
In this approach, you would create your resource policy granting access to the other account, but only for principals with a given tag. Then when you create the roles in the other account you add tags to them for the secrets they need to access. For example, the resource policy below grants GetSecretValue to account 123456789012 only when the tag "access-project" has the same value for both the secret and the accessing role:
{
"Version" : "2012-10-17",
"Statement" : [ {
"Effect" : "Allow",
"Principal": {"AWS": "123456789012" },
"Condition": {
"StringEquals": {
"aws:ResourceTag/access-project": "${aws:PrincipalTag/access-project}"
}
},
"Action" : "secretsmanager:GetSecretValue",
"Resource" : "*"
} ]
}
After adding this resource policy to the secret, you would also add the tag "access-project" to both the secret and the user/role. Note that this only grants GetSecretValue. It is probably a bad idea to let the user modify the the secret or the tags on the secret, but if you need to do so you would also include the other conditions from the referenced tutorial. Of course, you could also hard code the tags in the resource policy if you do not want to add tags to the secrets.
In general, this approach is a lot easier to manage since you do not need to keep updating the resource policy every time you add or remove a user/role. You would just add or remove the tags from the users and or secrets.
The alternate way to do this is to just open up the secret to the entire account, and then within that account limit who can access the secret via IAM policies (possibly still using tags as in the tutorial). Cross account access requires both the resource policy granting access and the IAM user/role policy granting access.
What exactly does this AWS role do?
The most relevant bits seem to be:
"Action": "sts:AssumeRole", and
"Service": "ec2.amazonaws.com"
The full role is here:
resource "aws_iam_role" "test_role" {
name = "test_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
From: https://www.terraform.io/docs/providers/aws/r/iam_role.html
To understand the meaning of this it is necessary to understand some details of how IAM Roles work.
An IAM role is similar to a user in its structure, but rather than it being accessed by a fixed set of credentials it is instead used by assuming the role, which means to request and obtain temporary API credentials that allow taking action with the privileges that are granted to the role.
The sts:AssumeRole action is the means by which such temporary credentials are obtained. To use it, a user or application calls this API using some already-obtained credentials, such as a user's fixed access key, and it returns (if permitted) a new set of credentials to act as the role. This is the mechanism by which AWS services can call into other AWS services on your behalf, by which IAM Instance Profiles work in EC2, and by which a user can temporarily switch access level or accounts within the AWS console.
The assume role policy determines which principals (users, other roles, AWS services) are permitted to call sts:AssumeRole for this role. In this example, the EC2 service itself is given access, which means that EC2 is able to take actions on your behalf using this role.
This role resource alone is not useful, since it doesn't have any IAM policies associated and thus does not grant any access. Thus an aws_iam_role resource will always be accompanied by at least one other resource to specify its access permissions. There are several ways to do this:
Use aws_iam_role_policy to attach a policy directly to the role. In this case, the policy will describe a set of AWS actions the role is permitted to execute, and optionally other constraints.
Use aws_iam_policy to create a standalone policy, and then use aws_iam_policy_attachment to associate that policy with one or more roles, users, and groups. This approach is useful if you wish to attach a single policy to multiple roles and/or users.
Use service-specific mechanisms to attach policies at the service level. This is a different way to approach the problem, where rather than attaching the policy to the role, it is instead attached to the object whose access is being controlled. The mechanism for doing this varies by service, but for example the policy attribute on aws_s3_bucket sets bucket-specific policies; the Principal element in the policy document can be used to specify which principals (e.g. roles) can take certain actions.
IAM is a flexible system that supports several different approaches to access control. Which approach is right for you will depend largely on how your organization approaches security and access control concerns: managing policies from the role perspective, with aws_iam_role_policy and aws_iam_policy_attachment, is usually appropriate for organizations that have a centralized security team that oversees access throughout an account, while service-specific policies delegate the access control decisions to the person or team responsible for each separate object. Both approaches can be combined, as part of a defense in depth strategy, such as using role- and user-level policies for "border" access controls (controlling access from outside) and service-level policies for internal access controls (controlling interactions between objects within your account).
More details on roles can be found in the AWS IAM guide IAM Roles. See also Access Management, which covers the general concepts of access control within IAM.
I am trying to create IAM Policy which restricts passing the IAM Role to an EC2 instance that if instance id does not equal to i-1234567890abcd
There is no error in the policy but there is no effect of this policy either. If I remove Condition from the below policy, it works but it restricts the role to be attached to any EC2 instance.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": ["iam:PassRole"],
"Resource": ["arn:aws:iam::000000000000:role/MyEC2InstanceSpecificRole"],
"Condition": {
"ArnNotEquals": {
"ec2:SourceInstanceARN": "arn:aws:ec2:us-east-1:000000000000:instance/i-1234567890abcd"
}
}
}
]
}
I suspect that this is not possible.
The Granting a User Permissions to Pass a Role to an AWS Service documentation states:
To pass a role (and its permissions) to an AWS service, a user must have permissions to pass the role to the service. This helps administrators ensure that only approved users can configure a service with a role that grants permissions. To allow a user to pass a role to an AWS service, you must grant the PassRole permission to the user's IAM user, role, or group.
When a user passes a role ARN as a parameter to any API that uses the role to assign permissions to the service, the service checks whether that user has the iam:PassRole permission. To limit the user to passing only approved roles, you can filter the iam:PassRole permission with the Resources element of the IAM policy statement.
Also on Using an IAM Role to Grant Permissions to Applications Running on Amazon EC2 Instances it states:
PassRole is not an API action in the same way that RunInstances or ListInstanceProfiles is. Instead, it's a permission that AWS checks whenever a role ARN is passed as a parameter to an API (or the console does this on the user's behalf). It helps an administrator to control which roles can be passed by which users.
The normal use-case for PassRole is to ensure that users do not grant AWS Services any more permissions that they should be allowed to use themselves. It tries to avoid a situation where a non-Admin user passes an Admin role to a service with the sinister intention of then using that service to access resources that they would not normally be allowed to access. For example, launching an Amazon EC2 instance with an Admin role, so that they can then login to that instance and issue Admin commands that they would not normally be entitled to use.
The above documentation suggests that the PassRole permission is evaluated to confirm their permission to pass a certain role to a certain service, rather than how that service is going to use the role itself (eg by then assigning it to an EC2 instance to generate STS credentials).