

# Using IAM policy conditions for fine-grained access control
Using conditions

When you grant permissions in DynamoDB, you can specify conditions that determine how a permissions policy takes effect. 

## Overview


In DynamoDB, you have the option to specify conditions when granting permissions using an IAM policy (see [Identity and Access Management for Amazon DynamoDB](security-iam.md)). For example, you can:
+ Grant permissions to allow users read-only access to certain items and attributes in a table or a secondary index.
+ Grant permissions to allow users write-only access to certain attributes in a table, based upon the identity of that user.

In DynamoDB, you can specify conditions in an IAM policy using condition keys, as illustrated in the use case in the following section.

### Permissions use case


In addition to controlling access to DynamoDB API actions, you can also control access to individual data items and attributes. For example, you can do the following:
+ Grant permissions on a table, but restrict access to specific items in that table based on certain primary key values. An example might be a social networking app for games, where all users' saved game data is stored in a single table, but no users can access data items that they do not own, as shown in the following illustration:  
![\[A use case which grants table-level access to a user but restricts access to specific data items.\]](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/images/info-hiding-horizontal.png)
+ Hide information so that only a subset of attributes is visible to the user. An example might be an app that displays flight data for nearby airports, based on the user's location. Airline names, arrival and departure times, and flight numbers are all displayed. However, attributes such as pilot names or the number of passengers are hidden, as shown in the following illustration:   
![\[A use case that displays only a subset of data to users, but hides certain attributes of the data.\]](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/images/info-hiding-vertical.png)

To implement this kind of fine-grained access control, you write an IAM permissions policy that specifies conditions for accessing security credentials and the associated permissions. You then apply the policy to users, groups, or roles that you create using the IAM console. Your IAM policy can restrict access to individual items in a table, access to the attributes in those items, or both at the same time.

You can optionally use web identity federation to control access by users who are authenticated by Login with Amazon, Facebook, or Google. For more information, see [Using web identity federation](WIF.md).

You use the IAM `Condition` element to implement a fine-grained access control policy. By adding a `Condition` element to a permissions policy, you can allow or deny access to items and attributes in DynamoDB tables and indexes, based upon your particular business requirements. 

The video below explains fine-grained access control in DynamoDB using IAM policy conditions.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/LbEmo_yulb0?si=VTSlNHVocAEYwhJi/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/LbEmo_yulb0?si=VTSlNHVocAEYwhJi)


## Understanding Fine-Grained Access Control in DynamoDB


Fine-grained access control in DynamoDB allows you to create precise permissions boundaries at multiple levels:

1. **Item-level access control:** Restrict users to only access items that contain specific key values, typically matching their identity or permission scope.

1. **Attribute-level access control:** Limit which attributes (columns) users can view or modify, enabling you to protect sensitive information while allowing access to non-sensitive data within the same items.

1. **Operation-specific controls:** Apply different permission rules based on the type of operation being performed.

These controls are implemented through IAM policies using DynamoDB-specific condition keys.

## Specifying conditions: Using condition keys


AWS provides a set of predefined condition keys (AWS-wide condition keys) for all AWS services that support IAM for access control. For example, you can use the `aws:SourceIp` condition key to check the requester's IP address before allowing an action to be performed. For more information and a list of the AWS-wide keys, see [Available Keys for Conditions](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#AvailableKeys) in the IAM User Guide.

The following are the DynamoDB service-specific condition keys that apply to DynamoDB.

**`dynamodb:LeadingKeys`**  
Represents the first key attribute of a table—in other words, the partition key. The key name `LeadingKeys` is plural, even if the key is used with single-item actions. In addition, you must use the `ForAllValues` modifier when using `LeadingKeys` in a condition.

**`dynamodb:Select`**  
Represents the `Select` parameter of a request. `Select` can be any of the following values:  
+ `ALL_ATTRIBUTES`
+ `ALL_PROJECTED_ATTRIBUTES`
+ `SPECIFIC_ATTRIBUTES`
+ `COUNT`
While often associated with Query and Scan operations, this condition key applies to all DynamoDB operations that return item attributes and is essential for controlling attribute access across all API actions. Using StringEqualsIfExists or similar constraints on this condition key will apply constraints on operations where this condition key applies, while ignoring it on operations where it does not apply.

**`dynamodb:Attributes`**  
Represents a list of the *top-level* attributes accessed by a request. A top-level attribute is accessed by a request if it, or any nested attribute that it contains, is specified in the request parameters. For example, a `GetItem` request that specifies a `ProjectionExpression` of `"Name, Address.City"`, the `dynamodb:Attributes` list would include "Name" and "Address". If the `Attributes` parameter is enumerated in a fine grained access control policy then consider also restricting `ReturnValues` and `Select` parameters to ensure restricted access to specified attributes across multiple API actions like `GetItem`, `Query`, and `Scan`.   
This condition is evaluated only on the attributes specified in the request (such as in a ProjectionExpression), not on attributes in the response. If no ProjectionExpression is provided in the request, all attributes will be returned regardless of any attribute restrictions in the policy. See the section "Ensuring attribute-based restrictions are enforced" below for details on how to properly secure attribute access.

**`dynamodb:ReturnValues`**  
Represents the `ReturnValues` parameter of a request. Depending on the API action, `ReturnValues` could be any of the following values:   
+ `ALL_OLD`
+ `UPDATED_OLD`
+ `ALL_NEW`
+ `UPDATED_NEW`
+ `NONE`

**`dynamodb:ReturnConsumedCapacity`**  
Represents the `ReturnConsumedCapacity` parameter of a request. `ReturnConsumedCapacity` can be one of the following values:  
+ `TOTAL`
+ `NONE`

**`dynamodb:FirstPartitionKeyValues`**  
Represents the first key attribute of a table—in other words, the first partition key. The key name `FirstPartitionKeyValues` is plural, even if the key is used with single-item actions. In addition, you must use the `ForAllValues` modifier when using `FirstPartitionKeyValues` in a condition. `FirstPartitionKeyValues` and `LeadingKeys` can used exchangeable.

**`dynamodb:SecondPartitionKeyValues`**  
Similar to `dynamodb:FirstPartitionKeyValues`. Represents resources' second partition key. The key name `SecondPartitionKeyValues` is plural, even if the key is used with single-item actions.

**`dynamodb:ThirdPartitionKeyValues`**  
Similar to `dynamodb:FirstPartitionKeyValues`. Represents resources' third partition key. The key name `ThirdPartitionKeyValues` is plural, even if the key is used with single-item actions.

**`dynamodb:FourthPartitionKeyValues`**  
Similar to `dynamodb:FirstPartitionKeyValues`. Represents resources' fourth partition key. The key name `FourthPartitionKeyValues` is plural, even if the key is used with single-item actions.

### Ensuring attribute-based restrictions are enforced


When using attribute-based conditions to restrict access to specific attributes, it's important to understand how these conditions are evaluated:
+ **Attribute conditions are evaluated only on attributes specified in the request**, not on attributes in the response.
+ **For read operations without a ProjectionExpression** (GetItem, Query, Scan, etc.), all attributes will be returned regardless of attribute restrictions in your policy. To prevent this potential exposure of sensitive data, implement both attribute conditions (`dynamodb:Attributes`) and a condition requiring specific attributes must be requested (`dynamodb:Select`).
+ **For write operations** (PutItem, UpdateItem, DeleteItem), the ReturnValues parameter can return complete items, potentially exposing restricted attributes even when the write operation itself complies with your policy. To prevent this exposure, implement both attribute conditions (`dynamodb:Attributes`) and restrictions on ReturnValues (`dynamodb:ReturnValues`) in your policy.

### Limiting user access


Many IAM permissions policies allow users to access only those items in a table where the partition key value matches the user identifier. For example, the game app preceding limits access in this way so that users can only access game data that is associated with their user ID. The IAM substitution variables `${www.amazon.com:user_id}`, `${graph.facebook.com:id}`, and `${accounts.google.com:sub}` contain user identifiers for Login with Amazon, Facebook, and Google. To learn how an application logs in to one of these identity providers and obtains these identifiers, see [Using web identity federation](WIF.md).

**Important**  
Fine-grained access control isn't supported for restricting global tables replication. Applying policy conditions for fine-grained access control to DynamoDB [service principals or service-linked roles](globaltables-security.md) used for global tables replication may interrupt replication within a global table. 

**Note**  
Each of the examples in the following section sets the `Effect` clause to `Allow` and specifies only the actions, resources, and parameters that are allowed. Access is permitted only to what is explicitly listed in the IAM policy.  
In some cases, it is possible to rewrite these policies so that they are deny-based (that is, setting the `Effect` clause to `Deny` and inverting all of the logic in the policy). However, we recommend that you avoid using deny-based policies with DynamoDB because they're difficult to write correctly, compared to allow-based policies. In addition, future changes to the DynamoDB API (or changes to existing API inputs) can render a deny-based policy ineffective.

### Example policies: Using conditions for fine-grained access control


This section shows several policies for implementing fine-grained access control on DynamoDB tables and indexes.

**Note**  
All examples use the us-west-2 Region and contain fictitious account IDs.

#### Example 1. Basic partition key-based access control with attribute restrictions


As an example, consider a mobile gaming app that lets players select from and play a variety of different games. The app uses a DynamoDB table named `GameScores` to keep track of high scores and other user data. Each item in the table is uniquely identified by a user ID and the name of the game that the user played. The `GameScores` table has a primary key consisting of a partition key (`UserId`) and sort key (`GameTitle`). Users only have access to game data associated with their user ID. A user who wants to play a game must belong to an IAM role named `GameRole`, which has a security policy attached to it.

To manage user permissions in this app, you could write a permissions policy such as the following:

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Sid":"AllowAccessToOnlyItemsMatchingUserID",
         "Effect":"Allow",
         "Action":[
            "dynamodb:GetItem",
            "dynamodb:BatchGetItem",
            "dynamodb:Query",
            "dynamodb:PutItem",
            "dynamodb:UpdateItem",
            "dynamodb:DeleteItem",
            "dynamodb:BatchWriteItem"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores"
         ],
         "Condition":{
            "ForAllValues:StringEquals":{
               "dynamodb:LeadingKeys":[
                  "${www.amazon.com:user_id}"
               ],
               "dynamodb:Attributes":[
                  "UserId",
                  "GameTitle",
                  "Wins",
                  "Losses",
                  "TopScore",
                  "TopScoreDateTime"
               ]
            },
            "StringEqualsIfExists":{
               "dynamodb:Select":"SPECIFIC_ATTRIBUTES"
            }
         }
      }
   ]
}
```

------

In addition to granting permissions for specific DynamoDB actions (`Action` element) on the `GameScores` table (`Resource` element), the `Condition` element uses the following condition keys specific to DynamoDB that limit the permissions as follows:
+ `dynamodb:LeadingKeys` – This condition key allows users to access only the items where the partition key value matches their user ID. This ID, `${www.amazon.com:user_id}`, is a substitution variable. For more information about substitution variables, see [Using web identity federation](WIF.md).
+ `dynamodb:Attributes` – This condition key limits access to the specified attributes so that only the actions listed in the permissions policy can return values for these attributes. In addition, the `StringEqualsIfExists` clause ensures that the app must always provide a list of specific attributes to act upon and that the app can't request all attributes.

When an IAM policy is evaluated, the result is always either true (access is allowed) or false (access is denied). If any part of the `Condition` element is false, the entire policy evaluates to false and access is denied.

**Important**  
If you use `dynamodb:Attributes`, you must specify the names of all of the primary key and index key attributes for the table and any secondary indexes that are listed in the policy. Otherwise, DynamoDB can't use these key attributes to perform the requested action.

IAM policy documents can contain only the following Unicode characters: horizontal tab (U\$10009), linefeed (U\$1000A), carriage return (U\$1000D), and characters in the range U\$10020 to U\$100FF.

#### Example 2: Grant permissions that limit access to items with a specific partition key value


The following permissions policy grants permissions that allow a set of DynamoDB actions on the `GamesScore` table. It uses the `dynamodb:LeadingKeys` condition key to limit user actions only on the items whose `UserID` partition key value matches the Login with Amazon unique user ID for this app.

**Important**  
The list of actions does not include permissions for `Scan` because `Scan` returns all items regardless of the leading keys.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	                    
   "Statement":[
      {
         "Sid":"FullAccessToUserItems",
         "Effect":"Allow",
         "Action":[
            "dynamodb:GetItem",
            "dynamodb:BatchGetItem",
            "dynamodb:Query",
            "dynamodb:PutItem",
            "dynamodb:UpdateItem",
            "dynamodb:DeleteItem",
            "dynamodb:BatchWriteItem"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores"
         ],
         "Condition":{
            "ForAllValues:StringEquals":{
               "dynamodb:LeadingKeys":[
                  "${www.amazon.com:user_id}"
               ]
            }
         }
      }
   ]
}
```

------

**Note**  
When using policy variables, you must explicitly specify version 2012-10-17 in the policy. The default version of the access policy language, 2008-10-17, does not support policy variables.

To implement read-only access, you can remove any actions that can modify the data. In the following policy, only those actions that provide read-only access are included in the condition.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	                    
   "Statement":[
      {
         "Sid":"ReadOnlyAccessToUserItems",
         "Effect":"Allow",
         "Action":[
            "dynamodb:GetItem",
            "dynamodb:BatchGetItem",
            "dynamodb:Query"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores"
         ],
         "Condition":{
            "ForAllValues:StringEquals":{
               "dynamodb:LeadingKeys":[
                  "${www.amazon.com:user_id}"
               ]
            }
         }
      }
   ]
}
```

------

**Important**  
If you use `dynamodb:Attributes`, you must specify the names of all of the primary key and index key attributes, for the table and any secondary indexes that are listed in the policy. Otherwise, DynamoDB can't use these key attributes to perform the requested action.

#### Example 3: Grant permissions that limit access to specific attributes in a table


The following permissions policy allows access to only two specific attributes in a table by adding the `dynamodb:Attributes` condition key. These attributes can be read, written, or evaluated in a conditional write or scan filter.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	                    
   "Statement":[
      {
         "Sid":"LimitAccessToSpecificAttributes",
         "Effect":"Allow",
         "Action":[
            "dynamodb:UpdateItem",
            "dynamodb:GetItem",
            "dynamodb:Query",
            "dynamodb:BatchGetItem",
            "dynamodb:Scan"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores"
         ],
         "Condition":{
            "ForAllValues:StringEquals":{
               "dynamodb:Attributes":[
                  "UserId",
                  "TopScore"
               ]
            },
            "StringEqualsIfExists":{
               "dynamodb:Select":"SPECIFIC_ATTRIBUTES",
               "dynamodb:ReturnValues":[
                  "NONE",
                  "UPDATED_OLD",
                  "UPDATED_NEW"
               ]
            }
         }
      }
   ]
}
```

------

**Note**  
The policy takes an allow list approach, which allows access to a named set of attributes. You can write an equivalent policy that denies access to other attributes instead. We don't recommend this deny list approach. Users can determine the names of these denied attributes by follow the principle of least privilege, as explained in Wikipedia at http://en.wikipedia.org/wiki/Principle\$1of\$1least\$1privilege, and use an allow list approach to enumerate all of the allowed values, rather than specifying the denied attributes.

This policy doesn't permit `PutItem`, `DeleteItem`, or `BatchWriteItem`. These actions always replace the entire previous item, which would allow users to delete the previous values for attributes that they are not allowed to access.

The `StringEqualsIfExists` clause in the permissions policy ensures the following:
+ If the user specifies the `Select` parameter, then its value must be `SPECIFIC_ATTRIBUTES`. This requirement prevents the API action from returning any attributes that aren't allowed, such as from an index projection.
+ If the user specifies the `ReturnValues` parameter, then its value must be `NONE`, `UPDATED_OLD`, or `UPDATED_NEW`. This is required because the `UpdateItem` action also performs implicit read operations to check whether an item exists before replacing it, and so that previous attribute values can be returned if requested. Restricting `ReturnValues` in this way ensures that users can only read or write the allowed attributes.
+ The `StringEqualsIfExists` clause assures that only one of these parameters — `Select` or `ReturnValues` — can be used per request, in the context of the allowed actions.

The following are some variations on this policy:
+ To allow only read actions, you can remove `UpdateItem` from the list of allowed actions. Because none of the remaining actions accept `ReturnValues`, you can remove `ReturnValues` from the condition. You can also change `StringEqualsIfExists` to `StringEquals` because the `Select` parameter always has a value (`ALL_ATTRIBUTES`, unless otherwise specified).
+ To allow only write actions, you can remove everything except `UpdateItem` from the list of allowed actions. Because `UpdateItem` does not use the `Select` parameter, you can remove `Select` from the condition. You must also change `StringEqualsIfExists` to `StringEquals` because the `ReturnValues` parameter always has a value (`NONE` unless otherwise specified).
+ To allow all attributes whose name matches a pattern, use `StringLike` instead of `StringEquals`, and use a multi-character pattern match wildcard character (\$1).

#### Example 4: Grant permissions to prevent updates on certain attributes


The following permissions policy limits user access to updating only the specific attributes identified by the `dynamodb:Attributes` condition key. The `StringNotLike` condition prevents an application from updating the attributes specified using the `dynamodb:Attributes` condition key.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	                    
   "Statement":[
      {
         "Sid":"PreventUpdatesOnCertainAttributes",
         "Effect":"Allow",
         "Action":[
            "dynamodb:UpdateItem"
         ],
         "Resource":"arn:aws:dynamodb:us-west-2:123456789012:table/GameScores",
         "Condition":{
            "ForAllValues:StringNotLike":{
               "dynamodb:Attributes":[
                  "FreeGamesAvailable",
                  "BossLevelUnlocked"
               ]
            },
            "StringEqualsIfExists":{
               "dynamodb:Select":"SPECIFIC_ATTRIBUTES",
               "dynamodb:ReturnValues":[
                  "NONE",
                  "UPDATED_OLD",
                  "UPDATED_NEW"
               ]
            }
         }
      }
   ]
}
```

------

Note the following:
+ The `UpdateItem` action, like other write actions, requires read access to the items so that it can return values before and after the update. In the policy, you limit the action to accessing only the attributes that are allowed to be updated by specifying the `dynamodb:ReturnValues` condition key. The condition key restricts `ReturnValues` in the request to specify only `NONE`, `UPDATED_OLD`, or `UPDATED_NEW` and doesn't include `ALL_OLD` or `ALL_NEW`.
+ The `StringEqualsIfExists` operator ensures that if `dynamodb:Select` or `dynamodb:ReturnValues` is present in the request, it must match the specified values. This prevents operations from returning complete items.
+ When restricting attribute updates, you should also control what data can be returned to prevent information disclosure of protected attributes.
+ The `PutItem` and `DeleteItem` actions replace an entire item, and thus allows applications to modify any attributes. So when limiting an application to updating only specific attributes, you should not grant permission for these APIs.

#### Example 5: Grant permissions to query only projected attributes in an index


The following permissions policy allows queries on a secondary index (`TopScoreDateTimeIndex`) by using the `dynamodb:Attributes` condition key. The policy also limits queries to requesting only specific attributes that have been projected into the index.

To require the application to specify a list of attributes in the query, the policy also specifies the `dynamodb:Select` condition key to require that the `Select` parameter of the DynamoDB `Query` action is `SPECIFIC_ATTRIBUTES`. The list of attributes is limited to a specific list that is provided using the `dynamodb:Attributes` condition key.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	                    
   "Statement":[
      {
         "Sid":"QueryOnlyProjectedIndexAttributes",
         "Effect":"Allow",
         "Action":[
            "dynamodb:Query"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores/index/TopScoreDateTimeIndex"
         ],
         "Condition":{
            "ForAllValues:StringEquals":{
               "dynamodb:Attributes":[
                  "TopScoreDateTime",
                  "GameTitle",
                  "Wins",
                  "Losses",
                  "Attempts"
               ]
            },
            "StringEquals":{
               "dynamodb:Select":"SPECIFIC_ATTRIBUTES"
            }
         }
      }
   ]
}
```

------

The following permissions policy is similar, but the query must request all of the attributes that have been projected into the index.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	                    
   "Statement":[
      {
         "Sid":"QueryAllIndexAttributes",
         "Effect":"Allow",
         "Action":[
            "dynamodb:Query"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores/index/TopScoreDateTimeIndex"
         ],
         "Condition":{
            "StringEquals":{
               "dynamodb:Select":"ALL_PROJECTED_ATTRIBUTES"
            }
         }
      }
   ]
}
```

------

#### Example 6: Grant permissions to limit access to certain attributes and partition key values


The following permissions policy allows specific DynamoDB actions (specified in the `Action` element) on a table and a table index (specified in the `Resource` element). The policy uses the `dynamodb:LeadingKeys` condition key to restrict permissions to only the items whose partition key value matches the user's Facebook ID.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	                    
   "Statement":[
      {
         "Sid":"LimitAccessToCertainAttributesAndKeyValues",
         "Effect":"Allow",
         "Action":[
            "dynamodb:UpdateItem",
            "dynamodb:GetItem",
            "dynamodb:Query",
            "dynamodb:BatchGetItem"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores",
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores/index/TopScoreDateTimeIndex"
         ],
         "Condition":{
            "ForAllValues:StringEquals":{
               "dynamodb:LeadingKeys":[
                  "${graph.facebook.com:id}"
               ],
               "dynamodb:Attributes":[
                  "attribute-A",
                  "attribute-B"
               ]
            },
            "StringEqualsIfExists":{
               "dynamodb:Select":"SPECIFIC_ATTRIBUTES",
               "dynamodb:ReturnValues":[
                  "NONE",
                  "UPDATED_OLD",
                  "UPDATED_NEW"
               ]
            }
         }
      }
   ]
}
```

------

Note the following:
+ Write actions allowed by the policy (`UpdateItem`) can only modify attribute-A or attribute-B.
+ Because the policy allows `UpdateItem`, an application can insert new items, and the hidden attributes will be null in the new items. If these attributes are projected into `TopScoreDateTimeIndex`, the policy has the added benefit of preventing queries that cause fetches from the table.
+ Applications cannot read any attributes other than those listed in `dynamodb:Attributes`. With this policy in place, an application must set the `Select` parameter to `SPECIFIC_ATTRIBUTES` in read requests, and only attributes in the allow list can be requested. For write requests, the application cannot set `ReturnValues` to `ALL_OLD` or `ALL_NEW` and it cannot perform conditional write operations based on any other attributes.

#### Example 7: Deny permissions to limit access to specific attributes in a table


The following policy denies access to sensitive attributes and ensures this restriction cannot be bypassed by omitting a projection expression. It allows general access to the `CustomerData` table while explicitly denying access to `SSN` and `CreditCardNumber` attributes.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:GetItem",
            "dynamodb:Query",
            "dynamodb:Scan"
         ],
         "Resource":"arn:aws:dynamodb:us-west-2:123456789012:table/CustomerData"
      },
      {
         "Effect":"Deny",
         "Action":[
            "dynamodb:GetItem",
            "dynamodb:Query",
            "dynamodb:Scan"
         ],
         "Resource":"arn:aws:dynamodb:us-west-2:123456789012:table/CustomerData",
         "Condition":{
            "ForAnyValue:StringEquals":{
               "dynamodb:Attributes":[
                  "SSN",
                  "CreditCardNumber"
               ]
            }
         }
      },
      {
         "Effect":"Deny",
         "Action":[
            "dynamodb:GetItem",
            "dynamodb:Query",
            "dynamodb:Scan"
         ],
         "Resource":"arn:aws:dynamodb:us-west-2:123456789012:table/CustomerData",
         "Condition":{
            "StringNotEqualsIfExists":{
               "dynamodb:Select":"SPECIFIC_ATTRIBUTES"
            }
         }
      }
   ]
}
```

------

## Related topics

+  [Identity and Access Management for Amazon DynamoDB](security-iam.md) 
+ [DynamoDB API permissions: Actions, resources, and conditions reference](api-permissions-reference.md)

# Using web identity federation


If you are writing an application targeted at large numbers of users, you can optionally use *web identity federation* for authentication and authorization. Web identity federation removes the need for creating individual users. Instead, users can sign in to an identity provider and then obtain temporary security credentials from AWS Security Token Service (AWS STS). The app can then use these credentials to access AWS services.

Web identity federation supports the following identity providers:
+ Login with Amazon
+ Facebook
+ Google

## Additional resources for web identity federation


The following resources can help you learn more about web identity federation:
+ The post [Web Identity Federation using the AWS SDK for .NET](https://aws.amazon.com/blogs/developer/web-identity-federation-using-the-aws-sdk-for-net) on the AWS Developer blog walks through how to use web identity federation with Facebook. It includes code snippets in C\$1 that show how to assume an IAM role with web identity and how to use temporary security credentials to access an AWS resource.
+ The [AWS Mobile SDK for iOS](https://aws.amazon.com/sdkforios/) and the [AWS Mobile SDK for Android](https://aws.amazon.com/sdkforandroid/) contain sample apps. They include code that shows how to invoke the identity providers, and then how to use the information from these providers to get and use temporary security credentials.
+ The article [Web Identity Federation with Mobile Applications](https://aws.amazon.com/articles/4617974389850313) discusses web identity federation and shows an example of how to use web identity federation to access an AWS resource.

## Example policy for web identity federation


To show how you can use web identity federation with DynamoDB, revisit the *GameScores* table that was introduced in [Using IAM policy conditions for fine-grained access control](specifying-conditions.md). Here is the primary key for *GameScores*.


****  

| Table Name | Primary Key Type | Partition Key Name and Type | Sort Key Name and Type | 
| --- | --- | --- | --- | 
| GameScores (UserId, GameTitle, ...) | Composite | Attribute Name: UserId Type: String | Attribute Name: GameTitle Type: String | 

Now suppose that a mobile gaming app uses this table, and that app needs to support thousands, or even millions, of users. At this scale, it becomes very difficult to manage individual app users, and to guarantee that each user can only access their own data in the *GameScores* table. Fortunately, many users already have accounts with a third-party identity provider, such as Facebook, Google, or Login with Amazon. So it makes sense to use one of these providers for authentication tasks.

To do this using web identity federation, the app developer must register the app with an identity provider (such as Login with Amazon) and obtain a unique app ID. Next, the developer needs to create an IAM role. (For this example, this role is named *GameRole*.) The role must have an IAM policy document attached to it, specifying the conditions under which the app can access *GameScores* table.

When a user wants to play a game, they sign in to their Login with Amazon account from within the gaming app. The app then calls AWS Security Token Service (AWS STS), providing the Login with Amazon app ID and requesting membership in *GameRole*. AWS STS returns temporary AWS credentials to the app and allows it to access the *GameScores* table, subject to the *GameRole* policy document.

The following diagram shows how these pieces fit together.

![\[A gaming app’s workflow. The app uses Amazon ID and AWS STS to obtain temporary credentials for accessing a DynamoDB table.\]](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/images/wif-overview.png)


**Web identity federation overview**

1. The app calls a third-party identity provider to authenticate the user and the app. The identity provider returns a web identity token to the app.

1. The app calls AWS STS and passes the web identity token as input. AWS STS authorizes the app and gives it temporary AWS access credentials. The app is allowed to assume an IAM role (*GameRole*) and access AWS resources in accordance with the role's security policy.

1. The app calls DynamoDB to access the *GameScores* table. Because it has assumed the *GameRole*, the app is subject to the security policy associated with that role. The policy document prevents the app from accessing data that does not belong to the user.

Once again, here is the security policy for *GameRole* that was shown in [Using IAM policy conditions for fine-grained access control](specifying-conditions.md):

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Sid":"AllowAccessToOnlyItemsMatchingUserID",
         "Effect":"Allow",
         "Action":[
            "dynamodb:GetItem",
            "dynamodb:BatchGetItem",
            "dynamodb:Query",
            "dynamodb:PutItem",
            "dynamodb:UpdateItem",
            "dynamodb:DeleteItem",
            "dynamodb:BatchWriteItem"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores"
         ],
         "Condition":{
            "ForAllValues:StringEquals":{
               "dynamodb:LeadingKeys":[
                  "${www.amazon.com:user_id}"
               ],
               "dynamodb:Attributes":[
                  "UserId",
                  "GameTitle",
                  "Wins",
                  "Losses",
                  "TopScore",
                  "TopScoreDateTime"
               ]
            },
            "StringEqualsIfExists":{
               "dynamodb:Select":"SPECIFIC_ATTRIBUTES"
            }
         }
      }
   ]
}
```

------

The `Condition` clause determines which items in *GameScores* are visible to the app. It does this by comparing the Login with Amazon ID to the `UserId` partition key values in `GameScores`. Only the items belonging to the current user can be processed using one of DynamoDB actions that are listed in this policy. Other items in the table cannot be accessed. Furthermore, only the specific attributes listed in the policy can be accessed.

# Preparing to use web identity federation


If you are an application developer and want to use web identity federation for your app, follow these steps:

1. **Sign up as a developer with a third-party identity provider.** The following external links provide information about signing up with supported identity providers:
   + [Login with Amazon Developer Center](http://login.amazon.com/)
   + [Registration](https://business.facebook.com/business/loginpage) on the Facebook site
   + [Using OAuth 2.0 to Access Google APIs](https://developers.google.com/accounts/docs/OAuth2) on the Google site

1. **Register your app with the identity provider.** When you do this, the provider gives you an ID that's unique to your app. If you want your app to work with multiple identity providers, you need to obtain an app ID from each provider.

1. **Create one or more IAM roles. **You need one role for each identity provider for each app. For example, you might create a role that can be assumed by an app where the user signed in using Login with Amazon, a second role for the same app where the user has signed in using Facebook, and a third role for the app where users sign in using Google.

   As part of the role creation process, you need to attach an IAM policy to the role. Your policy document should define the DynamoDB resources required by your app, and the permissions for accessing those resources.

For more information, see [About Web Identity Federation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc.html) in *IAM User Guide*. 

**Note**  
As an alternative to AWS Security Token Service, you can use Amazon Cognito. Amazon Cognito is the preferred service for managing temporary credentials for mobile apps. For more information, see [Getting credentials](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-credentials.html) in the *Amazon Cognito Developer Guide.* 

## Generating an IAM policy using the DynamoDB console


The DynamoDB console can help you create an IAM policy for use with web identity federation. To do this, you choose a DynamoDB table and specify the identity provider, actions, and attributes to be included in the policy. The DynamoDB console then generates a policy that you can attach to an IAM role.

1. Sign in to the AWS Management Console and open the DynamoDB console at [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1.  In the navigation pane, choose **Tables**. 

1.  In the list of tables, choose the table for which you want to create the IAM policy. 

1.  Select the **Actions** button, and choose **Create Access Control Policy**. 

1.  Choose the identity provider, actions, and attributes for the policy. 

    When the settings are as you want them, choose **Generate Policy**. The generated policy appears. 

1.  Choose **See Documentation**, and follow the steps required to attach the generated policy to an IAM role. 

# Writing your app to use web identity federation


To use web identity federation, your app must assume the IAM role that you created. From that point on, the app honors the access policy that you attached to the role.

At runtime, if your app uses web identity federation, it must follow these steps:

1. **Authenticate with a third-party identity provider.** Your app must call the identity provider using an interface that they provide. The exact way in which you authenticate the user depends on the provider and on what platform your app is running. Typically, if the user is not already signed in, the identity provider takes care of displaying a sign-in page for that provider.

   After the identity provider authenticates the user, the provider returns a web identity token to your app. The format of this token depends on the provider, but is typically a very long string of characters.

1. **Obtain temporary AWS security credentials.** To do this, your app sends a `AssumeRoleWithWebIdentity` request to AWS Security Token Service (AWS STS). This request contains the following:
   + The web identity token from the previous step
   + The app ID from the identity provider
   + The Amazon Resource Name (ARN) of the IAM role that you created for this identity provider for this app

   AWS STS returns a set of AWS security credentials that expire after a certain amount of time (3,600 seconds, by default).

   The following is a sample request and response from a `AssumeRoleWithWebIdentity` action in AWS STS. The web identity token was obtained from the Login with Amazon identity provider.

   ```
   GET / HTTP/1.1
   Host: sts.amazonaws.com
   Content-Type: application/json; charset=utf-8
   URL: https://sts.amazonaws.com/?ProviderId=www.amazon.com
   &DurationSeconds=900&Action=AssumeRoleWithWebIdentity
   &Version=2011-06-15&RoleSessionName=web-identity-federation
   &RoleArn=arn:aws:iam::123456789012:role/GameRole
   &WebIdentityToken=Atza|IQEBLjAsAhQluyKqyBiYZ8-kclvGTYM81e...(remaining characters omitted)
   ```

   

   ```
   <AssumeRoleWithWebIdentityResponse
     xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
     <AssumeRoleWithWebIdentityResult>
       <SubjectFromWebIdentityToken>amzn1.account.AGJZDKHJKAUUSW6C44CHPEXAMPLE</SubjectFromWebIdentityToken>
       <Credentials>
         <SessionToken>AQoDYXdzEMf//////////wEa8AP6nNDwcSLnf+cHupC...(remaining characters omitted)</SessionToken>
         <SecretAccessKey>8Jhi60+EWUUbbUShTEsjTxqQtM8UKvsM6XAjdA==</SecretAccessKey>
         <Expiration>2013-10-01T22:14:35Z</Expiration>
         <AccessKeyId>06198791C436IEXAMPLE</AccessKeyId>
       </Credentials>
       <AssumedRoleUser>
         <Arn>arn:aws:sts::123456789012:assumed-role/GameRole/web-identity-federation</Arn>
         <AssumedRoleId>AROAJU4SA2VW5SZRF2YMG:web-identity-federation</AssumedRoleId>
       </AssumedRoleUser>
     </AssumeRoleWithWebIdentityResult>
     <ResponseMetadata>
       <RequestId>c265ac8e-2ae4-11e3-8775-6969323a932d</RequestId>
     </ResponseMetadata>
   </AssumeRoleWithWebIdentityResponse>
   ```

1. **Access AWS resources.** The response from AWS STS contains information that your app requires in order to access DynamoDB resources:
   + The `AccessKeyID`, `SecretAccessKey`, and `SessionToken` fields contain security credentials that are valid for this user and this app only. 
   + The `Expiration` field signifies the time limit for these credentials, after which they are no longer valid.
   + The `AssumedRoleId` field contains the name of a session-specific IAM role that has been assumed by the app. The app honors the access controls in the IAM policy document for the duration of this session.
   + The `SubjectFromWebIdentityToken` field contains the unique ID that appears in an IAM policy variable for this particular identity provider. The following are the IAM policy variables for supported providers, and some example values for them:  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WIF.RunningYourApp.html)

For example IAM policies where these policy variables are used, see [Example policies: Using conditions for fine-grained access control](specifying-conditions.md#FGAC_DDB.Examples).

For more information about how AWS STS generates temporary access credentials, see [Requesting Temporary Security Credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) in *IAM User Guide*.

# DynamoDB API permissions: Actions, resources, and conditions reference
DynamoDB API permissions reference

When you are setting up [Identity and Access Management for Amazon DynamoDB](security-iam.md) and writing a permissions policy that you can attach to an IAM identity (identity-based policies), you can use the list of [Actions, resources, and condition keys for Amazon DynamoDB](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazondynamodb.html) in the *IAM User Guide* as a reference. The page lists each DynamoDB API operation, the corresponding actions for which you can grant permissions to perform the action, and the AWS resource for which you can grant the permissions. You specify the actions in the policy's `Action` field, and you specify the resource value in the policy's `Resource` field.

You can use AWS-wide condition keys in your DynamoDB policies to express conditions. For a complete list of AWS-wide keys, see the [IAM JSON policy elements reference](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#AvailableKeys) in the *IAM User Guide*.

In addition to the AWS-wide condition keys, DynamoDB has its own specific keys that you can use in conditions. For more information, see [Using IAM policy conditions for fine-grained access control](specifying-conditions.md).

## Related topics

+  [Identity and Access Management for Amazon DynamoDB](security-iam.md)
+ [Using IAM policy conditions for fine-grained access control](specifying-conditions.md)