In a traditional MySql Server situation, as the owner of a database, I create a User and from the database I grant certain access rights to the User object. An application can then (and only) access the database by supplying the password for the User.
I am confused and don't see a parallel when it comes to giving access to a DynamoDB table. From the DynamoDB Tables page, I can't find a means to grant permission for an IAM user to access a table. There is an Access Control tab, but that appears to be for Facebook/Google users.
I read about attaching policies but am confused further. How is access controlled if anyone can create a policy that can access all tables?
What am I missing? I just want to create a "login" for a Node application to access my DynamoDB table.
If anyone in your AWS account can create IAM policies you have a real security issue.
Only a few accounts should do that (Create IAM policies).
DynamoDB accesses work along with IAM user like you said, so, you need to do the following:
Create IAM groups to classify your IAM users, for example, DBAGroup for dbas, DEVGroup for developers and so on.
Create IAM policies to grant specific access to your DynamoDB tables for each group.
Apply the policies to the specific groups for granting accesses.
For login purposes, you need to develop a module that will verify the credentials with IAM service, so you need to execute IAM API calls. This module could be deployed within an EC2, could be a Javascript call to an API Gateway's endpoint along with a Lambda function, Etc.
What you need to do:
Create an account on IAM service that will be able to execute API calls to the IAM service for verifying credentials (Login and password).
This account should have only permissions for doing that (Verify user login and password).
Use the API credentials to be able to execute API calls.
If you don't want to create your own module for login purposes, take a look at Amazon Cognito
Amazon Cognito lets you add user sign-up/sign-in and access control to your web and mobile apps quickly and easily. Cognito scales to millions of users and supports sign-in with social identity providers such as Facebook, Google, and Amazon, and enterprise identity providers via SAML 2.0.
The last step is how your module execute API calls to IAM service? As you may know, we need API Credentials. So, using the logged user's credentials you will be able to execute API calls to read data from tables, execute CRUD operations, Etc.
To set specific permissions for certain tables as in SQL Server you must do this:
In Identity and Access Management (IAM) create a new security policy on the JSON tab:
Use the following JSON as an example to allow a full CRUD or remove the items within the "Action" section to allow only the desired items:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListAndDescribe",
"Effect": "Allow",
"Action": [
"dynamodb:List*",
"dynamodb:DescribeReservedCapacity*",
"dynamodb:DescribeLimits",
"dynamodb:DescribeTimeToLive"
],
"Resource": "*"
},
{
"Sid": "SpecificTable",
"Effect": "Allow",
"Action": [
"dynamodb:BatchGet*",
"dynamodb:DescribeStream",
"dynamodb:DescribeTable",
"dynamodb:Get*",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchWrite*",
"dynamodb:CreateTable",
"dynamodb:Delete*",
"dynamodb:Update*",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/MyTable"
}
]
}
Give the policy a name and save it.
After that, go to the Identity and Access Management (IAM) Users screen and create a new user as shown below.
Remember to set the field ** Access type ** as * Programmatic access *, it is not necessary to add the user to a group, click on "Atach existing policies directly" and add the policy previously created.
Finished! You already have everything you need to connect your application to Dynamodb.
Related
Is it possible to disable AWS S3 management console for the security reasons?
We don't want anyone including root/admin users to access customer files directly from the AWS S3. We should just have programmatic access to the files stored in S3.
If this is not possible, is it possible to stop listing the directories inside the bucket for all users ?
This is a tricky one to implement, however the following should be able to fulfill the requirements.
Programmatic Access Only
You need to define exactly which actions should be denied you would not want to block access completely otherwise you might lose the ability to do anything.
If you're in AWS you should use IAM roles, and a VPC endpoint to connect to the S3 service. Both of these support the ability to control access within your S3 buckets Bucket Policy.
You would use this to deny List* actions where the source is not the VPC endpoint. You could also deny where its not a specific subset of roles.
This works for all programmatic use cases and for people who login as an IAM user from the console, however this does not deny access to the root user.
Also bear in mind for any IAM user/IAM role that they do not have access unless you explicitly give it to them via an IAM policy.
Denying Access To The Root User
There is currently only one way to deny access to the root user of an AWS account (although you should share these credentials with anyone, even within your company) as that is using a Service Control Policy.
To do this the account would need to be part of an AWS organisation (as an organisational unit). If/once it is you would create a SCP that denies access to the root principal for the specific actions that you want.
An example of this policy for you would be
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RestrictS3ForRoot",
"Effect": "Deny",
"Action": [
"s3:List*"
],
"Resource": [
"*"
],
"Condition": {
"StringLike": {
"aws:PrincipalArn": [
"arn:aws:iam::*:root"
]
}
}
}
]
}
Yes, it is possible to disable the Management Console: Don't give users a password.
When creating IAM Users, there are two ways to provide credentials:
Sign-in Credentials (for the Console)
Access Key (for API calls)
Only give users an Access Key and they won't be able to login to the console.
However, please note that when when using the Management Console, users have exactly the same permissions as using an Access Key. Thus, if they can do it in the console, then they can do it via an API call (if they have an Access Key).
If your goal is to prevent anyone from accessing customer files, then you can add a Bucket Policy with a Deny on s3:* for the bucket, where the Principal is not the customer.
Please note, however, that the Root login can remove such a policy.
If the customers really want to keep their own data private, then they would need to create their own AWS account and keep their files within it, without granting you access.
I am writing a basic react native app where users will be able to register themselves to an AWS cognito userpool and log in with that identity to store/retrieve their data from S3. I only have one bucket and every user will have their own folder in that bucket. How can I restrict each user to their own folder in that case. Here is the scenario.
I created two users in the user pool.
I then created a federated identity for my userpool. This federated identity has two IAM roles, authorized and unauthorized.
I then added a policy to the auth role of federated identity.
Here is my policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "arn:aws:s3:::mybucket/${cognito-identity.amazonaws.com:sub}/*"
}
]
}
I then tried to retrieve data from S3 using Javascript SDK and I could ListObjects from "album-b207a8df-58e8-49cf-ba1b-0b48b7252291" where "b207a8df-58e8-49cf-ba1b-0b48b7252291" is the sub of "madi" user. Why was "test2" able to list that object?
Can you provide a snippet of the onClick_Cognito_receiptsdumpAuth_Role.*** ??
My guess (without your logs)
is that your policy is probably good, but you might have a policy
that grants list access to too much.
Your AWS class is being inited with your developer credentials
(which might have full Admin)
Cognito might have an issue and its
worth logging a support ticket.
Next steps I would try is
You might have a action:List* or equivalent
Also best hidden secret (it's not really a secret) is the policy simulator.
Test your policy against that and it will tell you if at least the policy is good and don't forget that iam policies are concatenated.
Lastly, if you can't figure out how the access is provided to the List Operation, you can enable CloudTrail to dump API logs to S3 and verify that the listobjects is being run by the cognito user you are expecting.
I've already gone through the documentation and it closely mirrors my use-case except that I cannot use Google, Facebook or Amazon as my identity provider, but I already have an enterprise level OAuth 2.0 access token for authenticated users.
I understand that I could possibly use Enterprise Federated support from AWS STS to get temporary credentials and use them to further access the AWS resources but I fail to understand how can i configure the IAM Policy to use these credentials to achieve horizontal information hiding.
I have certain tables in DynamoDB in which I store the details of all the users of my application and my application supports multiple tenants so I want the users of one tenant to NOT being able to access data of other tenants. The IAM policy that I could configure is of the type:
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${www.amazon.com:user_id}"]
}
}
Now my users are NOT logged in via Amazon ( or Google or Facebook ) and hence I cannot use the keys like "${www.amazon.com:user_id}" etc. Also my hash key for some tables are composite.
So my question is how to achieve multi-tenancy at the database level and be able to segregate or separate data per tenant i.e. to hide certain rows of my tables from the users who should not have access on it.
Is it possible to specify custom Policy Variables while defining the IAM policy and specify how to resolve those at runtime ? Or some other way be ?
My tables in Dynamo currently have composite hash keys, which are a combination of Tenant_ID and User_ID so can I specify some kind of rule in the IAM Policy so that I should be able to achieve horizontal information hiding ?
Please let me know if you need more information about my use case.
Regards,
Agraj
In order to enable fine-grained data access in DynamoDB, you must specify an IAM Policy Element Variable in the DynamoDB IAM policy.
A typical policy may look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "FullAccessToUserItems",
"Effect": "Allow",
"Action": [
"dynamodb:*"
],
"Resource": [
"arn:aws:dynamodb:*:table/*"
],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${cognito-identity.amazonaws.com:sub}"
]
}
}
}
]
}
Where ${cognito-identity.amazonaws.com:sub} is an IAM policy variable representing the user's sub in Cognito.
Unfortunately Amazon do not publish a list of available policy variables. What this does mean though is that your user management has to be managed through Amazon to enable fine grained security. You cannot define your own policy variables - they have to be pre-defined Amazon variables - hence fine grained security is only available where your users are managed in Amazon.
Additionally your DynamoDB partition key has to match the policy variable. For example you table partition key would have to be the Cognito sub.
If your OAuth token was received from Cognito you can simply post it to the Amazon Token Endpoint, which will give you back an id_token which contain the users Cognito sub.
I'm new to AWS. My client uses AWS to host his EC2 instances. Right now, we are trying to get me API access. Obviously, I need my authentication details to do this.
He set me up an IAM identity under his account, so I can login to the AWS web console and configure EC2 instances. I cannot, however, for the life of me, figure out where my API access keys are displayed. I don't have permissions to view 'My Account', which is where I imagine they'd be displayed.
So, what I'm asking, is how can he grant me API access through his account? How can I access the AWS API using my IAM identity?
Michael - sqlbot's answer is correct (+1), but not entirely complete given the comparatively recent but highly useful addition of Variables in AWS Access Control Policies:
Today we’re extending the AWS access policy language to include
support for variables. Policy variables make it easier to create
and manage general policies that include individualized access
control.
This enables implementation of an 'IAM Credentials Self Management' group policy, which would usually be assigned to the most basic IAM group like the common 'Users'.
Please note that the following solution still needs to be implemented by the AWS account owner (or an IAM user with permissions to manage IAM itself), but this needs to be done once only to enable credentials self management by other users going forward.
Official Solution
A respective example is included in the introductory blog post (and meanwhile has been available at Allow a user to manage his or her own security credentials in the IAM documentation too - Update: this example vanished again, presumably due to being applicable via custom solutions using the API only and thus confusing):
Variable substitution also simplifies allowing users to manage their
own credentials. If you have many users, you may find it impractical
to create individual policies that allow users to create and rotate
their own credentials. With variable substitution, this becomes
trivial to implement as a group policy. The following policy permits
any IAM user to perform any of the key and certificate related actions
on their own credentials. [emphasis mine]
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action":["iam:*AccessKey*","iam:*SigningCertificate*"],
"Resource":["arn:aws:iam::123456789012:user/${aws:username}"]
}
]
}
The resource scope arn:aws:iam::123456789012:user/${aws:username} ensures that every user is effectively only granted access to his own credentials.
Please note that this solution still has usability flaws depending on how AWS resources are accessed by your users, i.e. via API, CLI, or the AWS Management Console (the latter requires additional permissions for example).
Also, the various * characters are a wildcard, so iam:*AccessKey* addresses all IAM actions containing AccessKey (see IAM Policy Elements Reference for details).
Extended Variation
Disclaimer: The correct configuration of IAM policies affecting IAM access in particular is obviously delicate, so please make your own judgement concerning the security impact of the following solution!
Here's a more explicit and slightly extended variation, which includes AWS Multi-Factor Authentication (MFA) device self management and a few usability enhancements to ease using the AWS Management Console:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:CreateAccessKey",
"iam:DeactivateMFADevice",
"iam:DeleteAccessKey",
"iam:DeleteSigningCertificate",
"iam:EnableMFADevice",
"iam:GetLoginProfile",
"iam:GetUser",
"iam:ListAccessKeys",
"iam:ListGroupsForUser",
"iam:ListMFADevices",
"iam:ListSigningCertificates",
"iam:ListUsers",
"iam:ResyncMFADevice",
"iam:UpdateAccessKey",
"iam:UpdateLoginProfile",
"iam:UpdateSigningCertificate",
"iam:UploadSigningCertificate"
],
"Effect": "Allow",
"Resource": [
"arn:aws:iam::123456789012:user/${aws:username}"
]
},
{
"Action": [
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice",
"iam:ListVirtualMFADevices"
],
"Effect": "Allow",
"Resource": "arn:aws:iam::123456789012:mfa/${aws:username}"
}
]
}
"You" can't, but:
In IAM, under Users, after he selects your user, he needs to click Security Credentials > Manage Access Keys, and then choose "Create Access Key" to create an API Key and its associated Secret, associated with your IAM user. On the next screen, there's a message:
Your access key has been created successfully.
This is the last time these User security credentials will be available for download.
You can manage and recreate these credentials any time.
Where "manage" means "deactivate or delete," and "recreate" means "start over with a new one." The IAM admin can subsequently see the keys, but not the associated secrets.
From that screen, and only from that screen, and only right then, is where the IAM admin can view the both key and the secret associated with the key or download them to a CSV file. Subsequently, one with appropriate privileges can see the keys for a user within IAM but you can never view the secret again after this one chance (and it would be pretty preposterous if you could).
So, your client needs to go into IAM, under the user he created for you, and create an API key/secret pair, save the key and secret, and forward that information to you via an appropriately-secure channel... if he created it but didn't save the associated secret, he should delete the key and create a new one associated with your username.
If you don't have your own AWS account, you should sign up for one so you can go into the console with full permissions as yourself and understand the flow... it might make more sense than my description.
My use case is to allow users to create new user/password, create a folder for each user and allow them to upload files.
Then when they come back, they can login with the user/password and download their files (which are used within our product)
I managed to get most of the staff done using the C# API - very happy!
The only problem is that I cannot find a way to authenticate the user with IAM - using the username/password.
I don't want the end user to worry about key/secrets and long strings, they are suppose to be able to transfer these details (and access to data files) with other users to help them.
Is there a way to authenticate an IAM username/password? Thanks, Uri.
You need to use 'federated access' - with that you have users with accounts and passwords on your system. Then they authenticate with your system, and you grant them access for up to 36 hours through a session based system (encrypted cookie, or memcache etc) to have access to their folder.
You can do this with a web application or with a standalone C# windows app that authenticates to your server.
With a web app, your users log in, user/pass, then you store an encrypted cookie or similar, so that your web app can make pre signed posts, download files, etc while they are logged in. There is no need for them to ever see an AWSID/Secret.
As far as I understand the question, this seems to be available. You just need to have them log into the console from the sign-in link provided on the AWS IAM homepage.
You will then need to assign a password to the user account in question and add a policy for them so they can access the S3 bucket in question. You need the list all my buckets to get past the first screen of the console. I just tried it and something like the following works:
{
"Statement": [
{
"Sid": "Stmt1363222128",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
},
{
"Sid": "Stmt136328293",
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::your_bucket_name"
]
}
]
}
No. You will need to use the key/secrets. That is the short answer. When you create a new user in IAM it will give that specific user their own key/secrets. All they need to do is login, grab their key/secret and punch it in.
Manage IAM users and their access - You can create users in IAM,
assign users individual security credentials (i.e., access keys,
password, Multi Factor Authentication devices) or request temporary
security credentials to provide users access to AWS services and
resources. You can manage permissions to control which operations a
user can perform. - aws.amazon.com/iam