Can I specify an AWS DynamoDB policy based on Cognito ID? - amazon-dynamodb

Can I apply a policy to an AWS DynamoDB table but restrict it based on the Cognito ID of the user accessing it?
E.g. A Customer table has a primary hash key equal to the Cognito ID. When anyone but the user sharing the same ID tries to get the item they will receive an unauthorised exception.
(Non DynanoDB policies are probably also valid.)

You should be able to do something like this using the same techniques as those for using an ID Provider. You should use the Cognito identifier as the key in the policy:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query"
],
"Resource": ["arn:aws:dynamodb:REGION:123456789012:table/UserData"],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"]}
}
}]
}

Related

Indexing the partition key in Azure Cosmos DB

Suppose I've the following data in my container:
{
"id": "1DBF704E-1623-4844-DC86-EFA729A5C048",
"firstName": "Wylie",
"lastName": "Ramsey",
"country": "AZ",
"city": "Tucson"
}
Where I use the field "id" as the item id, and the field "country" as the partition key, when I query on specific partition key:
SELECT * FROM c WHERE c.country = "AZ"
(get all the people in "AZ")
Should I add "country" as an index or I will get it by default, since I declered "country" as my partition key?
Is there a diference when using the SDK (meaning: adding the new PartitionKey("AZ") option and then sending the query as mentioned above)?
I created a collection with 50,000 records and disabled indexing on all properties.
Indexing policy:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [], // Included nothing
"excludedPaths": [
{
"path": "/\"_etag\"/?"
},
{
"path": "/*" // Exclude all paths
}
]
}
Querying by id cost 2.85 RUs.
Querying by PartitionKey cost 580 RUs.
Indexing policy with PartitionKey (country) added:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/country/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
},
{
"path": "/*" // Exclude all paths
}
]
}
Adding an index on the PartitionKey brought it down to 2.83 RUs.
So the answer to this is Yes, if you have disabled default indexing policies and need to search by partition key then you should add an index to it.
In my opinion, it's a good practice to query with partition key in cosmosdb sql api, here's the offical doc related to it.
By the way, cosmosdb sql api indexes all the properties by default. If you'd like to cover the default setting and customise the indexing policy, this doc may provide more details.

how to create a policy for DynamoDB where the user id is equal to DyanmoDB table name?

I am trying to create a DDB policy whereby the Cognito user id (sub) should be equal to the DynamoDB table name. The table name in DDB is the user's id (sub).
So the policy should limit access to the user's table for that user only.
Below is a pseudo policy I have created.
What is unclear to me is how do I specify that the user id ( sub ) should be equal to the DDB table name ?
{
"Version": "2020-11-01",
"Statement": [
{
"Sid": "xxxxxxxxxxxxxx",
"Effect": "Allow",
"Action": [
"dynamodb:Scan",
"dynamodb:Query",
],
"Resource": [ "arn:aws:dynamodb:<REGION>:<ACCOUNT_ID>:table/<${www.amazon.com:user_id}>"]
}
DDB TABLE NAME SHOULD MATCH USER ID HERE ${www.amazon.com:user_id}
]
}
Unfortunately you cannot currently do it with DynamoDB. This is because the table resource for DynamoDB does no support any condition keys (see https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazondynamodb.html#amazondynamodb-resources-for-iam-policies).
The only thing you could possibly do is to limit access per leading keys using the dynamodb:LeadingKeys condition. This again would only work for the Query action. Does not work on Scan (obviously). Your policy would then look something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Query"
],
"Resource": ["arn:aws:dynamodb:*:*:table/MyTable"],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"]
}
}
}
]
}

AWS AppSync IAM DynamoDb Role

I am trying to create a simple IAM role to have my AppSync service connect to my DynamoDb database, but because AppSync is in preview, IAM does not recognize AppSync as a service. How do I create an IAM role for to let AppSync have full access to DynamoDb?
The trusted relationships side looks something like this
Example Trusted Relationships Doc
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "appsync.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
The policy doc is basically the same as always
Example Policy Doc
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
If you are using a CloudFormation template, it might look like this
Example CloudFormation Template
AppSyncRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "appsync.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
-
PolicyName: "appsync-policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "dynamodb:PutItem"
- "dynamodb:UpdateItem"
- "dynamodb:DeleteItem"
- "dynamodb:GetItem"
- "dynamodb:Query"
- "dynamodb:Scan"
Resource: "*"

ARM Template - create SQL Server firewall rule for Web App

I have created SQL Server and Database, Web App, published website and database and get to the log on screen of the website.
When I log in I receive a 500 including the IP address of the web app which currently isn't allowed to access the newly created SQL Server.
I'd very much like to harvest the assigned IP address (suspect it is AZURE internal IP address) to create a firewall rule in the template.
I'm successfully doing things like adding app settings for storage account keys and database connections strings. And these are working nicely.
Very frustrating to not be able to find any reference to the internal IP of the web site. I've tried the object explorer in the azure portal.
Suggestions appreciated!
Andy
If you are using Azure SQL, about how to set Azure Database firewall, please refer to the document.
Very frustrating to not be able to find any reference to the internal IP of the web site?
If want to let Azure service to access Azure SQL database, we just need to set
Allow access to Azure services on. And default value is on.
We also could get the outbound IPs, we can get them from the azure resources(https://resources.azure.com/) then add the outboundIpAddresses to the Azure SQL firewall rule allowed IP list.
Note : For Azure WebApp, the outboundIpAddresses are not static ips, they may be changed when we restart the WebApp or change WebApp service plan.
If we want to add firewall rule via ARM template, we could use the following demo code:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"testfirewallAdminLogin": {
"type": "string",
"minLength": 1
},
"testfirewallAdminLoginPassword": {
"type": "securestring"
}},
"variables": {
"testfirewallName": "[concat('testfirewall', uniqueString(resourceGroup().id))]"},
"resources": [
{
"name": "[variables('testfirewallName')]",
"type": "Microsoft.Sql/servers",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01-preview",
"dependsOn": [ ],
"tags": {
"displayName": "testfirewall"
},
"properties": {
"administratorLogin": "[parameters('testfirewallAdminLogin')]",
"administratorLoginPassword": "[parameters('testfirewallAdminLoginPassword')]"
},
"resources": [
{
"name": "AllowAllWindowsAzureIps",
"type": "firewallrules",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01-preview",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', variables('testfirewallName'))]"
],
"properties": {
"startIpAddress": "x.x.x.x",
"endIpAddress": "x.x.x.x"
}
}
]
}],
"outputs": {
}
}

Allow a DynamoDB User to modify a subset of documents

How can I create a policy in DynamoDB, which allows the corresponding IAM users to modify just a subset of the documents in a table?
For example, let's say there is an attribute published,
and I want this IAM user to perform PutItem and UpdateItem
on documents which have published: false.
You can only use DynamoDB Fine-Grained Access Control on the hash key value. You could save an item with "draft" pre-pended to the hash-key value and use the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:UpdateItem",
],
"Resource": [
"arn:aws:dynamodb:REGION:ACCOUNT_NUMBER:table/TABLE_NAME"
],
"Condition": {
"ForAllValues:StringLike": {
"dynamodb:LeadingKeys": ["draft*"],
}
}
}
]
}
Adapted from https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/FGAC_DDB.html

Resources