AWS IAM Policy for restricting instances by associated IAM role - powershell

What I'm trying to do (continuing off on a question I asked previously: How can I filter AWS Instances by IAM role in powershell and get the private ip address of that instance?) is get the private ip addresses of instances with a specific IAM Role. And I've got a code that works perfectly:
$filter = New-Object Amazon.EC2.Model.Filter -Property #{Name = "iam-instance-profile.arn"; Value = "arn:aws:iam::123456789012:instance-profile/TestRole"}
$ec2 = #(Get-EC2Instance -Filter $filter)
$ec2instances = $ec2.instances
$ipaddress = $ec2instances.privateipaddress
However, now instead of doing the filter in the code, I'd like to create an IAM Policy that restricts the user to only be able to get information on the instances that have a specific IAM Role. So if they try to get-ec2instance (for example), it should only return information on the relevant instances and not all instances in the account.
This is my IAM Policy that I have:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:DescribeInstances"
],
"Effect": "Allow",
"Resource": [
"*"
],
"Condition": {
"ArnEquals": {
"ec2:InstanceProfile": "arn:aws:iam::12356789102:instance-profile/TestRole"
}
}
}
]
}
However when I run get-ec2instance on Powershell, I am told that I'm not authorised to perform that action. I think that might be because get-ec2instance is only applicable to all instances but I'm not sure.
I would appreciate the help, thanks!

There is no option so far where in you can restrict an IAM user to see a specific EC2 instance.
There is only one API call exists ec2-describe-instances which shows one needs to have all the permission on all instances or none.

The reason for the issue is that get-ec2instance is trying to describe all of your instances including instances that doesn't have appropriate role assigned to it.
When talking about describing EC2 instances or listing S3 buckets, you should be able to list everything, otherwise you receive a 403 error.
I could suggest you to restrict your access with IAM for the security purpose only and continue filtering your instances using the code iteslf.
Please let me know if it works for you.
P. S. You may have went in a wrong way when decided to use IAM roles in order to organize your access.
AWS provide a feature called "Resource tagging". The direct purpose of it is to organize your resources and apply permissions based on the structure.
More information here:
http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html#iam-policy-example-ec2-tag-permissions

Related

Is there a way to find the service associated with a serviceId on google admin?

By running Privileges.list on google admin sdk we get a JSON looking like this:
{
"kind": "admin#directory#privilege",
"etag": "\"JCPRxFaiNR1s5TJ6ecIH8OpGdY4efiOYXbIB65itOzY/l3mP5LVwu5mUzpHpCwuZ6dUl8sQ\"",
"serviceId": "00tyjcwt49hs5nq",
"serviceName": "play_for_work",
"privilegeName": "MANAGE_EXTERNALLY_HOSTED_APK_UPLOAD_IN_PLAY",
"isOuScopable": false
},
{
"kind": "admin#directory#privilege",
"etag": "\"JCPRxFaiNR1s5TJ6ecIH8OpGdY4efiOYXbIB65itOzY/0pXB8E7QTg03vLTGIizjP3RJ_KM\"",
"serviceId": "02w5ecyt3pkeyqi",
"privilegeName": "MANAGE_PLAY_FOR_WORK_STORE",
"isOuScopable": false
}
Where the second privilege doesn't contain a serviceName, just a serviceId.
What can we do with that serviceId? Is there a way to find the associated service using it?
I've inquired with some Google sources and it appears that they are aware that some serviceNames are not available, and there's no public list available. It may be confidential for some reason or they just prefer to keep it internal for now and they may or may not have plans for it in the future. Even the privileges.list API documentation mentions that the serviceId is an "obfuscated ID of the service", so we can at least tell that services and their IDs are important to them. This is a common practice.
The good thing is that, as far as I could tell, these service IDs and their names are only used in the privileges list API and they seem there mostly for descriptive purposes. The list also rarely changes so if you need to list them in your application you could assign them your own names if they are missing. You can use the privilegeName field as a guide, for example.
If you still have questions about it you can try to file a post in their issue tracker at the product feedback link at the bottom of the page.

Azure DevOps - Unable to Create Var Group using Azure DevOps API and Auth Token

Requirements: We would like to create a Variable Group (along with some variables) in a given Project.
Option1: We are able to create a new Variable Group successfully
when we create a request via PostMan using PAT Token which has FULL access.
Option2: Our end goal is to invoke the ADO Rest API in the Web App which uses
OAuth. When the end user logs in and make a call (pls see the input
details below) we are getting '401 Un Authorized - The user is not authorized to access this resource.' error. The Web App's application has the Variable Groups manage scope as shown below.
TroubleShooting: As part of troubleshooting, for Option1 which uses PAT (with full access) in Postman, we have updated the permissions of the PAT to just have Create, Read and Manage Var Groups as shown below.
Now, even the Option1 is not working after making the PAT to have Custom Defined access.
Are we missing something?
Postman Details:
URL: https://dev.azure.com/myorgname/_apis/distributedtask/variablegroups?api-version=6.0-preview.2
Verb: Post
Headers: Authorization: Basic
Body:
{
"name": "This is ignored",
"description": "This is ignored",
"type": "Vsts",
"variables": {
"BuildConfiguration": {
"value": "Release"
}
},
"variableGroupProjectReferences": [
{
"name": "VarGroup",
"description": "The variable group to store the information about the variables using in the Pipeline",
"projectReference": {
"id": "#ProjectId#",
"name": "#ProjectName#"
}
}
]
}
I can also reproduce your issue with option 1, not only Read, create, & manage for Variable Groups, even I select all the scopes via Custom defined, it still does not work.
According to this doc - https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/manage-pats-with-policies-for-administrators?view=azure-devops#restrict-creation-of-full-scoped-pats
Some of our public APIs are currently unassociated with a PAT scope, and can therefore only be used with “full-scoped” PATs. Because of this, restricting the creation of full-scoped PATs might block some workflows. We're working to identify and document the affected APIs and eventually associate them with the appropriate scope. For now, these workflows can be unblocked by using the allow list.
I believe this should be the reason for this issue, there may be some additional permissions to create variable groups. For option 2, there may be a similar cause.
So in this case, you may need to use the Full access PAT temporarily, as mentioned in the doc We're working to identify and document the affected APIs and eventually associate them with the appropriate scope.

How to add Keycloak realm role to group via REST API

I want to assign the realm role "TEST_ROLE_123" to a group, I am using
PUT /admin/realms/ataccamaone/groups/{group-id}
{
"realmRoles":["TEST_ROLE_123"]
}
I got group-id from /admin/realms/ataccamaone/groups/
However I get the response 204 No Content and in the Keycloak console I do not see the assignment.
I tried to reproduce your problem and find that PUT /admin/realms/ataccamaone/groups/{group-id} can only edit group name.
Inspect into "Network" tab of browser, I see it uses another URL to map roles to groups. And steps to do this via Admin REST API are:
Obtain PAT as described in https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_protection_whatis_obtain_pat section
Following steps use this PAT as Bearer token (in "Authorization" header). I guess you've already got this.
Call GET http://localhost:8080/auth/admin/realms/realm1/roles to get list of roles, including their name and id values.
Call GET http://localhost:8080/auth/admin/realms/realm1/groups to get list of groups, including their ids
Call POST http://localhost:8080/auth/admin/realms/realm1/groups/{group-id}/role-mappings/realm with following body:
[
{
"id": "9083cac3-4280-497d-b973-7713a5fb12b4", // role-id
"name": "secretary" // role-name
}
]
Call DELETE with URL and body same as step 4 to remove roles from group.
I've faced same issue and corrected it with using a GROUP, Basically I've added the preferred ROLE into the User Groups ROLE LIST and used that specific user group while creating the user via REST API.
Eg:- ADMIN_USER_GROUP -> INCLUDED ('ADMIN_ROLE')
Then User creation API Request should be like below,
{
"firstName": "Sergey",
"lastName": "Kargopolov",
"email": "test4#test.com",
"enabled": "true",
"credentials": [
{
"value": "123"
}
],
"groups": [
"ADMIN_USER_GROUP"
]
}

Escaping AWS IAM Policy Variable for API Gateway Permissions

I currently have SAML integration setup and working as expected between my authentication provider (auth0) and AWS/AWS API Gateway.
The complications arise however when defining an AWS Policy with the ${saml:sub} variable.
Here's an example of my configuration:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:*"
],
"Resource": [
"arn:aws:execute-api:us-west-2:[removed]/*/GET/customers/${saml:sub}"
]
}
]
}
Basically I want to ensure that this endpoint is only accessible by the currently auth'd in user (based on their saml:sub). The currently auth'd user should not be able to access another customers record. Seems like this should be a potentially common use-case.
Auth0 automatically assigns saml:sub and the format of the id is something like this
auth0|429
I'm assuming the issue currently lies with the pipe character being there and it comparing it to an automatically escaped value when the request is made to the API Gateway URL via the browser. Because of this, i'm assuming access is denied to the resource because
auth0|429 != auth0%7C429.
Is there a way within an IAM policy to work around this?
Is there a potential workaround on the Auth0 side to assign a different value to ${saml:sub}?
Appreciate all the potential solutions above! Ultimately I ended up abandoning SAML integration between Auth0 and AWS and opting for a custom authorizer via a lambda function inside of API Gateway. This allowed for a little more flexible setup.
For anyone else facing a similar scenario, I came across this GitHub project that's been working great so far:
https://github.com/jghaines/lambda-auth0-authorizer
I modified the project for our own purposes a little bit, but essentially what we've done is mapped our internal user ID to the AWS principalId.
On the API Gateway side we've setup a /customers/me resource and then on the integration request modified the URL Path Parameters like so:
Integration Request Screenshot
Our policy in our lambda function is setup like so
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "324342",
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"arn:aws:execute-api:us-west-2:[removed]/*/GET/customers/me"
]
}
]
}
This allows for dynamic access to the endpoint and only returns data specific to the logged in user.
In my opinion the issue you described should be solved/handled from within the AWS Policy configuration, but since I'm not knowledgeable on that I'll offer you a workaround from the perspective of avoiding potential troublesome characters.
You can configure and override the default SAML mappings that Auth0 uses to output user information and as such control the attributes used for each of the output claims and the SAML subject.
Check SAML attributes mapping for an overview on how to do this.
Additionally, check SAML configuration via rules for a detailed view of all the available options.
By default, Auth0 will check the following claims in order to decide the one to be used as the SAML subject:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
The IAM Policy won't be able to recognize ${saml:sub} in the actual resource ARN. Beyond that, API GW won't automatically understand a SAML assertion.
Are you using a custom authorizer Lambda function to parse the SAML assertion? If so you would want to parse out the 'sub' field and insert it directly into the policy returned from the authorizer like so
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:*"
],
"Resource": [
"arn:aws:execute-api:us-west-2:[removed]/*/GET/customers/auth0|429"
]
}
]
}
If you're already that far and it's still not working as expected, then you're right, it may be that the URI is not being normalized depending on the client/browser encoding. I'd have to test that. But as long as your backend treats /customers/auth0|429 == /customers/auth0%7C429, you could safely build a policy that allows both unencoded and encoded versions of the resource:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:*"
],
"Resource": [
"arn:aws:execute-api:us-west-2:[removed]/*/GET/customers/auth0|429",
"arn:aws:execute-api:us-west-2:[removed]/*/GET/customers/auth0%7C429"
]
}
]
}
If you're not using custom authorizers, please elaborate on what your setup looks like. But either way, unfortunately the IAM policy won't ever be able to evaluate the ${var} syntax in the resource block.

What policy Action(s) on what Resource(s) are required to run New-EC2Tag from Powershell?

I'm attempting to run New-EC2Tag, getting the following error:
New-EC2Tag : You are not authorized to perform this operation.
The user policy is as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ec2:DescribeInstances","ec2:CreateTags"],
"Resource": "arn:aws:ec2:ap-southeast-2:<my_account_id>:instance/*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/OctopusTentacle": "yes"
}
}
}
]
}
It works fine in the Policy Simulator as above.
If I remove the condition and set Resource to * it works. Removing the condition or setting Resource to * alone do not work. I am running this as local Administrator on the instance.
What else is New-EC2Tag accessing/doing that I need to grant access to?
If New-EC2Tag works when clearing the Condition and wildcarding the Resource, then we should be inspecting both of those.
From some investigation, New-EC2Tag's related API action is CreateTags. According to Supported Resources and Conditions for Amazon EC2 API Actions, some API actions do not support ARNs. This seems to be the case with CreateTags, as it requests that you specify a resource ID instead. This is also corraborated by the "Supported Resources..." documentation I linked above, which does not list CreateTags as supporting arns.
In this case, the documentation recommends that you set the policy as such:
If the API action does not support ARNs, use the * wildcard to specify
that all resources can be affected by the action.
So that leaves the condition... the tag. The tag that you are using as a condition needs to already exist on the instance for the policy to be applied as you expect. An example from the policy simulator, where the tag already exists:
Another consideration is that the action may likewise not support conditions, but I haven't found anything to back that up.