Amazon Keyspaces identity-based policy examples - Amazon Keyspaces (for Apache Cassandra)

Amazon Keyspaces identity-based policy examples

By default, IAM users and roles don't have permission to create or modify Amazon Keyspaces resources. They also can't perform tasks using the console, CQLSH, AWS CLI, or AWS API. An IAM administrator must create IAM policies that grant users and roles permission to perform specific API operations on the specified resources they need. The administrator must then attach those policies to the IAM users or groups that require those permissions.

To learn how to create an IAM identity-based policy using these example JSON policy documents, see Creating policies on the JSON tab in the IAM User Guide.

Policy best practices

Identity-based policies determine whether someone can create, access, or delete Amazon Keyspaces resources in your account. These actions can incur costs for your AWS account. When you create or edit identity-based policies, follow these guidelines and recommendations:

  • Get started with AWS managed policies and move toward least-privilege permissions – To get started granting permissions to your users and workloads, use the AWS managed policies that grant permissions for many common use cases. They are available in your AWS account. We recommend that you reduce permissions further by defining AWS customer managed policies that are specific to your use cases. For more information, see AWS managed policies or AWS managed policies for job functions in the IAM User Guide.

  • Apply least-privilege permissions – When you set permissions with IAM policies, grant only the permissions required to perform a task. You do this by defining the actions that can be taken on specific resources under specific conditions, also known as least-privilege permissions. For more information about using IAM to apply permissions, see Policies and permissions in IAM in the IAM User Guide.

  • Use conditions in IAM policies to further restrict access – You can add a condition to your policies to limit access to actions and resources. For example, you can write a policy condition to specify that all requests must be sent using SSL. You can also use conditions to grant access to service actions if they are used through a specific AWS service, such as AWS CloudFormation. For more information, see IAM JSON policy elements: Condition in the IAM User Guide.

  • Use IAM Access Analyzer to validate your IAM policies to ensure secure and functional permissions – IAM Access Analyzer validates new and existing policies so that the policies adhere to the IAM policy language (JSON) and IAM best practices. IAM Access Analyzer provides more than 100 policy checks and actionable recommendations to help you author secure and functional policies. For more information, see IAM Access Analyzer policy validation in the IAM User Guide.

  • Require multi-factor authentication (MFA) – If you have a scenario that requires IAM users or a root user in your AWS account, turn on MFA for additional security. To require MFA when API operations are called, add MFA conditions to your policies. For more information, see Configuring MFA-protected API access in the IAM User Guide.

For more information about best practices in IAM, see Security best practices in IAM in the IAM User Guide.

Using the Amazon Keyspaces console

Amazon Keyspaces does not require specific permissions to access the Amazon Keyspaces console. You need at least read-only permissions to list and view details about the Amazon Keyspaces resources in your AWS account. If you create an identity-based policy that is more restrictive than the minimum required permissions, the console won't function as intended for entities (IAM users or roles) with that policy.

Two AWS managed policies are available to the entities for Amazon Keyspaces console access.

  • AmazonKeyspacesReadOnlyAccess – This policy grants read-only access.

  • AmazonKeyspacesFullAccess – This policy grants administrator access.

For more information about Amazon Keyspaces managed policies, see AWS managed policies for Amazon Keyspaces.

Allow users to view their own permissions

This example shows how you might create a policy that allows IAM users to view the inline and managed policies that are attached to their user identity. This policy includes permissions to complete this action on the console or programmatically using the AWS CLI or AWS API.

{ "Version": "2012-10-17", "Statement": [ { "Sid": "ViewOwnUserInfo", "Effect": "Allow", "Action": [ "iam:GetUserPolicy", "iam:ListGroupsForUser", "iam:ListAttachedUserPolicies", "iam:ListUserPolicies", "iam:GetUser" ], "Resource": ["arn:aws:iam::*:user/${aws:username}"] }, { "Sid": "NavigateInConsole", "Effect": "Allow", "Action": [ "iam:GetGroupPolicy", "iam:GetPolicyVersion", "iam:GetPolicy", "iam:ListAttachedGroupPolicies", "iam:ListGroupPolicies", "iam:ListPolicyVersions", "iam:ListPolicies", "iam:ListUsers" ], "Resource": "*" } ] }

Accessing Amazon Keyspaces tables

The following is a sample policy that grants read-only (SELECT) access to the system tables. For all samples, replace the Region and account ID in the Amazon Resource Name (ARN) with the one from your service.

Note

To connect with a standard driver, a user must have at least SELECT access to the system tables, because most drivers read the system keyspaces/tables on connection.

{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "cassandra:Select" ], "Resource":[ "arn:aws:cassandra:us-east-1:111122223333:/keyspace/system*" ] } ] }

The following sample policy adds read-only access to a user table.

{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "cassandra:Select" ], "Resource":[ "arn:aws:cassandra:us-east-1:111122223333:/keyspace/mykeyspace/table/mytable", "arn:aws:cassandra:us-east-1:111122223333:/keyspace/system*" ] } ] }

The following sample policy assigns read/write access to a user table and read access to the system tables.

Note

System tables are read-only.

{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "cassandra:Select", "cassandra:Modify" ], "Resource":[ "arn:aws:cassandra:us-east-1:111122223333:/keyspace/mykeyspace/table/mytable", "arn:aws:cassandra:us-east-1:111122223333:/keyspace/system*" ] } ] }

The following sample policy allows a user to create tables in keyspace mykeyspace.

{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "cassandra:Create", "cassandra:Select" ], "Resource":[ "arn:aws:cassandra:us-east-1:111122223333:/keyspace/mykeyspace/*", "arn:aws:cassandra:us-east-1:111122223333:/keyspace/system*" ] } ] }

Accessing Amazon Keyspaces using the authentication plugin

In the following example, you run an application that uses the Amazon Keyspaces authentication plugin to access Amazon Keyspaces from an EC2 instance associated with an IAM role to query your Amazon Keyspaces table. The application returns all orders from a table called orders for a given customer ID.

The example includes the following steps:

  1. Create an Amazon Keyspaces keyspace and table, and insert records.

  2. Launch an EC2 instance and associate it with an IAM role.

    Define the IAM policy that gives the EC2 instance permissions to your Amazon Keyspaces table.

  3. Deploy and run the sample code on the EC2 instance to query your Amazon Keyspaces table.

Create a sample table

To start, create a keyspace and a table, and insert some records. To create the orders table, you can use the CQL Editor on the Amazon Keyspaces console, or you can use cqlsh. For more information, see Using the cqlsh-expansion to connect to Amazon Keyspaces.

First, create a keyspace and a table with the following table schema.

create keyspace acme with replication = {'class': 'SimpleStrategy', 'replication_factor' : 1 }; create table acme.orders ( customer_id text, order_timestamp timestamp, order_id uuid, primary key (customer_id, order_timestamp)) with clustering order by (order_timestamp desc);

Next, insert a few order records into the table.

insert into acme.orders (customer_id, order_timestamp, order_id) values ('1234', toTimestamp(now()), uuid()); insert into acme.orders (customer_id, order_timestamp, order_id) values ('1234', toTimestamp(now()), uuid()); insert into acme.orders (customer_id, order_timestamp, order_id) values ('1234', toTimestamp(now()), uuid()); insert into acme.orders (customer_id, order_timestamp, order_id) values ('1234', toTimestamp(now()), uuid());

Launch an EC2 instance associated with the IAM role

Create the IAM role that will be associated with the EC2 instance that will run the application.

Save the following document to a file named iam-keyspaces-ec2-role.json.

{ "Version":"2012-10-17", "Statement":{ "Effect":"Allow", "Principal":{ "Service":"ec2.amazonaws.com" }, "Action":"sts:AssumeRole" } }

To give the EC2 instance read-only access to your orders table, create the following IAM policy. Replace the Region and account ID in the Amazon Resource Name (ARN) with that from your Amazon Keyspaces account.

{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":"cassandra:Select", "Resource":[ "arn:aws:cassandra:us-east-2:111122223333:/keyspace/acme/table/orders", "arn:aws:cassandra:us-east-2:111122223333:/keyspace/system*" ] } ] }

Save the following document to a file named iam-keyspaces-ec2-policy.json.

Note

You must include permissions for the system keyspace in the policy because the driver has to access this keyspace to retrieve cluster metadata.

To launch an EC2 instance and associate the created IAM role with the instance, follow the steps in Launching an instance with an IAM role. To associate the role with an existing EC2 instance, see Attaching an IAM role.

Note

Choose an Amazon Linux AMI with Java pre-installed for this example. If you are using an existing Amazon Linux instance, confirm that you have Java installed, or complete this step using the command sudo yum install java-11-amazon-corretto-headless.

Deploying and running the code

To deploy and run the code to query your Amazon Keyspaces table, use the following steps:

  1. Download the sample code from GitHub.

  2. Compile the sample code using Apache Maven.

  3. Copy the JAR file to the EC2 instance, and run the application.

This example uses a sample application that implements the Amazon Keyspaces authentication plugin to access the table using the IAM role. In your own code, you must first integrate the plugin following the steps in Step-by-step tutorial to connect to Amazon Keyspaces using the 4.x DataStax Java driver for Apache Cassandra and the SigV4 authentication plugin.

After downloading the sample from the GitHub repository, compile the code using Apache Maven version 3.6.3 or higher using the following command.

mvn package

This creates the following JAR file with all dependencies included in the target directory.

aws-sigv4-auth-cassandra-java-driver-examples-1.0.0.jar

Copy this JAR file along with the cassandra_truststore.jks located in the sample code directory to the EC2 instance. Then run the application using the following command. Replace the AWS Region us-east-2 with the Region that you are using.

java -Djavax.net.ssl.trustStore=./cassandra_truststore.jks \ -Djavax.net.ssl.trustStorePassword=amazon -jar \ aws-sigv4-auth-cassandra-java-driver-examples-1.0.0.jar \ us-east-2 cassandra.us-east-2.amazonaws.com 1234

This command results in the records that you inserted into the table earlier. The application accessed the table using temporary credentials assigned to the IAM role session and with the read-only permissions defined in the IAM policy.

Amazon Keyspaces resource access based on tags

You can use conditions in your identity-based policy to control access to Amazon Keyspaces resources based on tags. These policies control visibility of the keyspaces and tables in the account. Note that tag-based permissions for system tables behave differently when requests are made using the AWS SDK compared to Cassandra Query Language (CQL) API calls via Cassandra drivers and developer tools.

  • To make List and Get resource requests with the AWS SDK when using tag-based access, the caller needs to have read access to system tables. For example, Select action permissions are required to read data from system tables via the GetTable operation. If the caller has only tag-based access to a specific table, an operation that requires additional access to a system table will fail.

  • For compatibility with established Cassandra driver behavior, tag-based authorization policies are not enforced when performing operations on system tables using Cassandra Query Language (CQL) API calls via Cassandra drivers and developer tools.

The following example shows how you can create a policy that grants permissions to a user to view a table if the table's Owner contains the value of that user's user name. In this example you also give read access to the system tables.

{ "Version":"2012-10-17", "Statement":[ { "Sid":"ReadOnlyAccessTaggedTables", "Effect":"Allow", "Action":"cassandra:Select", "Resource":[ "arn:aws:cassandra:us-east-2:111122223333:/keyspace/myKeyspace/table/*", "arn:aws:cassandra:us-east-2:111122223333:/keyspace/myKeyspace/system*" ], "Condition":{ "StringEquals":{ "aws:ResourceTag/Owner":"${aws:username}" } } } ] }

You can attach this policy to the IAM users in your account. If a user named richard-roe attempts to view an Amazon Keyspaces table, the table must be tagged Owner=richard-roe or owner=richard-roe. Otherwise, he is denied access. The condition tag key Owner matches both Owner and owner because condition key names are not case-sensitive. For more information, see IAM JSON policy elements: Condition in the IAM User Guide.

The following policy grants permissions to a user to create tables with tags if the table's Owner contains the value of that user's user name.

{ "Version": "2012-10-17", "Statement": [ { "Sid": "CreateTagTableUser", "Effect": "Allow", "Action": [ "cassandra:Create", "cassandra:TagResource" ], "Resource": "arn:aws:cassandra:us-east-2:111122223333:/keyspace/mykeyspace/table/*", "Condition":{ "StringEquals":{ "aws:RequestTag/Owner":"${aws:username}" } } } ] }