dynamodb:UpdateItem Vertical Access Control: Things to keep in mind
As simple as you may think it’d be, I came across a lot of “gotchas” when trying to provide a simple column-level access control for my dynamo db table.
Let’s take a simple example.
Let’s say you’ve a table called products with 4 columns:
- product_id (Partition Key)
- product_name (String)
- product_store_id (String)
- product_metadata (map)
The JSON representation should look like this:
{
"product_id": "123",
"product_name": "tomatoes",
"product_store_id": "walmart_44556",
"product_metadata":{
"price_history": {
"2002": 100,
"2003": 110
}
}
}
Now, you want people with Role A to only perform dynamodb:UpdateItem on product_name column.
Here’s the policy you’d attach to your Role A to achieve this:
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"PolicySid1",
"Effect":"Allow",
"Action":[
"dynamodb:UpdateItem"
],
"Resource":[
"arn:aws:dynamodb:us-east-1:123456789012:table/products"
],
"Condition":{
"ForAllValues:StringEquals":{
"dynamodb:Attributes":[
"product_id",
"product_name"
]
}
}
}
]
}
Your update expression should look something like this (using aws-sdk for javascript):
// Load the AWS SDK for Node.js
const AWS = require('aws-sdk');
// Set the region
AWS.config.update({ region: 'us-east-1' });
// Create DynamoDB document client
const docClient = new AWS.DynamoDB.DocumentClient();
// Define the parameters for the update operation
const params = {
TableName: 'products',
Key: {
'product_id': '123' // Replace with the primary key of the item you want to update
},
UpdateExpression: 'set product_name = :newName',
ExpressionAttributeValues: {
':newName': 'Apples' // Replace with the new product name
},
ReturnValues: 'UPDATED_NEW'
};
// Perform the update operation
docClient.update(params, (err, data) => {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Update succeeded:", JSON.stringify(data, null, 2));
}
});
Here are some gotchas that you need to keep in mind:
- You always need your partition-key to be present in the dynamodb:Attributes for the policy to work. I did not have it initially, neither was it specified anywhere in the docs which made me go crazy.
- Policy will not work with level 1+ updates. Eg. If ,you want your policy to allow a user to update only product_metadata.price_history, AWS does not support it. You will only be able to implement access control on parent properties of the table.
Priyank Rupareliya is a Senior Software Engineer focused on architecting solutions revolving around Cloud, DevOps, Containerization, Backend and Frontend.