

# Enabling cross account access
<a name="feature-store-cross-account-access"></a>

The access permissions are read-only, read-write, and admin permissions. The permission name, description, and list of specific APIs available for each permission are listed in the following:
+ Read-only permission (`AWSRAMPermissionSageMakerFeatureGroupReadOnly`): The read privilege allows resource consumer accounts to read records in the shared feature groups and view details and metadata. 
  + `DescribeFeatureGroup`: Retrieves details about a feature group and its configuration
  + `DescribeFeatureMetadata`: Shows the metadata for a feature within a feature group
  + `BatchGetRecord`: Retrieves a batch of records from a feature group
  + `GetRecord`: Retrieves a record from a feature group
+ Read-write permission (`AWSRAMPermissionSagemakerFeatureGroupReadWrite`): The read-write privilege allows resource consumer accounts to write records to, and delete records from, the shared feature groups, in addition to read permissions.
  + `PutRecord`: Writes a record to a feature group
  + `DeleteRecord`: Removes a record from a feature group
  + APIs listed in `AWSRAMPermissionSageMakerFeatureGroupReadOnly`
+ Admin permission (`AWSRAMPermissionSagemakerFeatureGroupAdmin`): The admin privilege allows the resource consumer accounts to update the description and parameters of features within the shared feature groups, update the configuration of the shared feature groups, in addition to read-write permissions.
  + `DescribeFeatureMetadata`: Shows the metadata for a feature within a feature group
  + `UpdateFeatureGroup`: Updates a feature group configuration
  + `UpdateFeatureMetadata`: Updates description and parameters of a feature in the feature group
  + APIs listed in `AWSRAMPermissionSagemakerFeatureGroupReadWrite`

In the following topics you can learn how to share online store and offline feature groups—there are differences between the two when it comes to sharing.

**Topics**
+ [Share online feature groups with AWS Resource Access Manager](feature-store-cross-account-access-online-store.md)
+ [Cross account offline store access](feature-store-cross-account-access-offline-store.md)

# Share online feature groups with AWS Resource Access Manager
<a name="feature-store-cross-account-access-online-store"></a>

With AWS Resource Access Manager (AWS RAM) you can securely share Amazon SageMaker Feature Store online feature groups with other AWS accounts. Members of your team can explore and access feature groups that span multiple accounts, promoting data consistency, streamlining collaboration, and reducing duplication of effort.

The resource owner account can share resources with other individual AWS accounts by granting permissions using AWS RAM. The resource consumer account is the AWS account with whom a resource is shared, limited by the permissions granted from the resource owner account. If you are an organization, you may want to take advantage of AWS Organizations, with which you can share resources with individual AWS accounts, with all accounts in your organization, or in an Organization Unit (OU), without having to apply permissions to each account. For instructional videos and more information about AWS RAM concepts and benefits, see [What is AWS Resource Access Manager?](https://docs.aws.amazon.com/ram/latest/userguide/what-is.html) in the AWS RAM User Guide.

Note that there is a soft maximum limit to the transactions per second (TPS) per API per AWS account. The maximum TPS limit applies to *all* transactions on the resources within the resource owner account, so transactions from the resource consumer accounts also count towards this maximum limit. For information about service quotas and how to request a quota increase, see [AWS service quotas](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html).

This section covers how the resource owner account can choose feature groups and grant access privileges (read-only, read-write, and admin) to resource consumer accounts, and then how the resource consumer accounts with access privileges can use those feature groups. The access permissions do not allow for the resource consumer accounts to search and discover feature groups. To allow for resource consumer accounts to search and discover feature groups from the resource owner account, the resource owner account must grant discoverability permission to the resource consumer accounts, where all of the feature groups within the resource owner account are discoverable by the resource consumer accounts. For more information about granting the discoverability permission, see [Enabling cross account discoverability](feature-store-cross-account-discoverability.md).

The following topics show how to share Feature Store online store resources using the AWS RAM console. For information about sharing your resources and granting permissions within AWS using the AWS RAM console or AWS Command Line Interface (AWS CLI), see [Sharing your AWS resources](https://docs.aws.amazon.com/ram/latest/userguide/getting-started-sharing.html).

**Topics**
+ [Share your feature group entities](feature-store-cross-account-access-online-store-share-feature-group.md)
+ [Use online store shared resources with access permissions](feature-store-cross-account-access-online-store-use.md)

# Share your feature group entities
<a name="feature-store-cross-account-access-online-store-share-feature-group"></a>

As the resource owner account you can use the feature group resource type for Amazon SageMaker Feature Store to share feature group entities, by creating a resource share in AWS Resource Access Manager (AWS RAM). 

Use the following instructions along with the [Sharing your AWS resources](https://docs.aws.amazon.com/ram/latest/userguide/getting-started-sharing.html#getting-started-sharing-create) instructions in the AWS RAM User Guide.

When sharing the feature group resource type using the AWS RAM console, you need to make the following choices.

1. **Specify resource share details**: 
   + Resource type: Choose **SageMaker AI Feature Groups**.
   + ARN: Choose your feature group ARN with the format: `arn:aws:sagemaker:us-east-1:111122223333:feature-group/your-feature-group-name`.

     `us-east-1` is the region of the resource, `111122223333` is the resource owner account ID, and `your-feature-group-name` is the feature group you are sharing.
   + Resource ID: Choose the feature group, `your-feature-group-name`, to which you want to grant access permissions.

1. **Associate managed permissions**: 
   + Managed permission: Choose the access permission. For more information about access permissions, see [Enabling cross account access](feature-store-cross-account-access.md).

1. **Grant access to principals**:
   + Choose the principal type (AWS account, Organization, Organizational unit, IAM role, or IAM user) and enter the appropriate ID or ARN.

1. **Review and create**: 
   + Review then choose **Create resource share**.

Granting any access permission does not grant resource consumer accounts the discoverability permission, so the resource consumer accounts with access permissions cannot search and discover those feature groups. To allow for resource consumer accounts to search and discover feature groups from the resource owner account, the resource owner account must grant the discoverability permission to the resource consumer accounts, where *all* of the feature groups within the resource owner account are discoverable by the resource consumer accounts. For more information about granting the discoverability permission, see [Enabling cross account discoverability](feature-store-cross-account-discoverability.md).

If the resource consumer accounts are only granted access permissions, the feature group entities can still be viewed on AWS RAM. To view resources on AWS RAM, see [Access AWS resources shared with you](https://docs.aws.amazon.com/ram/latest/userguide/working-with-shared.html) in the AWS RAM User Guide.

It may take a few minutes for the resource share and principal, or resource consumer account, associations to complete. Once the resource share and principal associations are set, the specified resource consumer accounts receive an invitation to join the resource share. The resource consumer accounts can view and accept the invitations by opening the [Shared with me: Resource shares](https://console.aws.amazon.com/ram/home#SharedResourceShares) page in the AWS RAM console. Invitations are not sent in these cases:
+ If you are part of an organization in AWS Organizations and sharing in your organization is enabled, then principals in the organization automatically get access to the shared resources without invitations.
+ If you share with the AWS account that owns the resource, then the principals in that account automatically get access to the shared resources without invitations.

For more information about accepting and using a resource share in AWS RAM, see [Using shared AWS resources](https://docs.aws.amazon.com/ram/latest/userguide/getting-started-shared.html) in the AWS RAM User Guide.

## Share online store feature groups using the AWS SDK for Python (Boto3)
<a name="feature-store-cross-account-access-online-store-python-sdk-example"></a>

You can use the AWS SDK for Python (Boto3) for AWS RAM APIs to create a resource share. The following code is an example of a resource owner account ID `111122223333` creating a resource share named `'test-cross-account-fg'`, sharing the feature group named `'my-feature-group'` with the resource consumer account ID `444455556666` while granting the `AWSRAMPermissionSageMakerFeatureGroupReadOnly` permission. For more information about access permissions, see [Enabling cross account access](feature-store-cross-account-access.md). To use the Python SDK for AWS RAM APIs, you need to attach AWS RAM full access managed policy with execution role. See [create\$1resource\$1share](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ram/client/create_resource_share.html) AWS RAM API for more details.

```
import boto3

# Choose feature group name
feature_group_name = 'my-feature-group' # Change to your feature group name 

# Share 'my-feature-group' with other account
ram_client = boto3.client("ram")
response = ram_client.create_resource_share(
    name='test-cross-account-fg', # Change to your custom resource share name
    resourceArns=[
        'arn:aws:sagemaker:us-east-1:111122223333:feature-group/' + feature_group_name, # Change 111122223333 to the resource owner account ID
    ],
    principals=[
        '444455556666', # Change 444455556666 to the resource consumer account ID
    ],
    permissionArns = ["arn:aws:ram::aws:permission/AWSRAMPermissionSageMakerFeatureGroupReadOnly"]
)
```

Principals are actors in a security system. In a resource-based policy, the allowed principals are IAM users, IAM roles, the root account, or another AWS service.

# Use online store shared resources with access permissions
<a name="feature-store-cross-account-access-online-store-use"></a>

The resource owner account must grant permissions to resource consumer accounts to allow for discoverability, read-only, write, or admin privileges with a shared resource. In the following sections, we provide instructions on how to accept an invitation to access shared resources and provide examples showing how to view and interact with shared feature groups.

**Accept an invitation to access shared resources using AWS RAM**

As the resource consumer account, you will receive an invitation to join a resource share once the resource owner account has granted permission. To accept the invitation to any shared resources, open the [Shared with me: Resource shares](https://console.aws.amazon.com/ram/home#SharedResourceShares) page in the AWS RAM console to view and respond to invitations. Invitations are not sent in these cases:
+ If you are part of an organization in AWS Organizations and sharing in your organization is enabled, then principals in the organization automatically get access to the shared resources without invitations.
+ If you share with the AWS account that owns the resource, then the principals in that account automatically get access to the shared resources without invitations.

For more information about accepting and using a resource share in AWS RAM, see [Using shared AWS resources](https://docs.aws.amazon.com/ram/latest/userguide/getting-started-shared.html) in the AWS RAM User Guide.

## View shared resources on the AWS RAM console
<a name="feature-store-cross-account-access-online-store-use-view"></a>

Granting any access permissions does not grant resource consumer accounts the discoverability permission, so the resource consumer accounts with access permissions cannot search and discover those feature groups. To allow for resource consumer accounts to search and discover feature groups from the resource owner account, the resource owner account must grant the discoverability permission to the resource consumer accounts, where all of the feature groups within the resource owner account are discoverable by the resource consumer accounts. For more information about granting the discoverability permission, see [Enabling cross account discoverability](feature-store-cross-account-discoverability.md).

To view the shared resources on the AWS RAM console, open the [Shared with me: Resource shares](https://console.aws.amazon.com/ram/home#SharedResourceShares) page in the AWS RAM console. 

## Read and write actions with a shared feature groups example
<a name="feature-store-cross-account-access-online-store-use-read-write-actions"></a>

Once your resource consumer account is granted the appropriate permissions by the resource owner account, you can perform actions on the shared resources using the Feature Store SDK. You can do this by providing the resource ARN as the `FeatureGroupName`. To obtain the Feature Group ARN, you can use the AWS SDK for Python (Boto3) [https://boto3.amazonaws.com/v1/documentation/api/1.26.98/reference/services/sagemaker/client/describe_feature_group.html#describe-feature-group](https://boto3.amazonaws.com/v1/documentation/api/1.26.98/reference/services/sagemaker/client/describe_feature_group.html#describe-feature-group) function or use the console UI. For information about using the console UI to view feature group details, see [View feature group details from the console](feature-store-use-with-studio.md#feature-store-view-feature-group-detail-studio).

The following examples use `PutRecord` and `GetRecord` with a shared feature group entity. See the request and response syntax in the AWS SDK for Python (Boto3) documentation for [https://boto3.amazonaws.com/v1/documentation/api/1.26.98/reference/services/firehose/client/put_record.html#put-record](https://boto3.amazonaws.com/v1/documentation/api/1.26.98/reference/services/firehose/client/put_record.html#put-record) and [https://boto3.amazonaws.com/v1/documentation/api/1.26.98/reference/services/sagemaker-featurestore-runtime/client/get_record.html#get-record](https://boto3.amazonaws.com/v1/documentation/api/1.26.98/reference/services/sagemaker-featurestore-runtime/client/get_record.html#get-record).

```
import boto3

sagemaker_featurestore_runtime = boto3.client('sagemaker-featurestore-runtime')

# Put record into feature group named 'test-fg' within the resource owner account ID 111122223333
featurestore_runtime.put_record(
    FeatureGroupName="arn:aws:sagemaker:us-east-1:111122223333:feature-group/test-fg", 
    Record=[value.to_dict() for value in record] # You will need to define record prior to calling PutRecord
)
```

```
import boto3

sagemaker_featurestore_runtime = boto3.client('sagemaker-featurestore-runtime')

# Choose record identifier
record_identifier_value = str(2990130)

# Get record from feature group named 'test-fg' within the resource owner account ID 111122223333
featurestore_runtime.get_record(
    FeatureGroupName="arn:aws:sagemaker:us-east-1:111122223333:feature-group/test-fg", 
    RecordIdentifierValueAsString=record_identifier_value
)
```

For more information about granting permissions to feature group entities, see [Share your feature group entities](feature-store-cross-account-access-online-store-share-feature-group.md).

# Cross account offline store access
<a name="feature-store-cross-account-access-offline-store"></a>

 Amazon SageMaker Feature Store allows users to create a feature group in one account (Account A) and configure it with an offline store using an Amazon S3 bucket in another account (Account B). You can set this up using the steps in the following section.

**Topics**
+ [Step 1: Set up the offline store access role in Account A](#feature-store-setup-step1)
+ [Step 2: Set up an offline store Amazon S3 bucket in Account B](#feature-store-setup-step2)
+ [Step 3: Set up an offline store AWS KMS encryption key in Account A](#feature-store-setup-step3)
+ [Step 4: Create a feature group in Account A](#feature-store-setup-step4)

## Step 1: Set up the offline store access role in Account A
<a name="feature-store-setup-step1"></a>

First, set up a role for Amazon SageMaker Feature Store to write the data into the offline store. The simplest way to accomplish this is to create a new role using the `AmazonSageMakerFeatureStoreAccess` policy or to use an existing role that already has the `AmazonSageMakerFeatureStoreAccess` policy attached. This document refers to this policy as `Account-A-Offline-Feature-Store-Role-ARN`. 

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetBucketAcl",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::*SageMaker*",
                "arn:aws:s3:::*Sagemaker*",
                "arn:aws:s3:::*sagemaker*"
            ]
        }
    ]
}
```

------

The preceding code snippet shows the `AmazonSageMakerFeatureStoreAccess` policy. The `Resource` section of the policy is scoped down by default to S3 buckets with names that contain `SageMaker`, `Sagemaker`, or `sagemaker`. This means the offline store Amazon S3 bucket being used must follow this naming convention. If this is not your case, or if you want to further scope down the resource, you can copy and paste the policy to your Amazon S3 bucket policy in the console, customize the `Resource` section to be `arn:aws:s3:::your-offline-store-bucket-name`, and then attach to the role. 

Additionally, this role must have AWS KMS permissions attached. At a minimum, it requires the `kms:GenerateDataKey` permission to be able to write to the offline store using your customer managed key. See Step 3 to learn about why a customer managed key is needed for the cross account scenario and how to set it up. The following example shows an inline policy: 

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:*:111122223333:key/*"
        }
    ]
}
```

------

The `Resource` section of this policy is scoped to any key in Account A. To further scope this down, after setting up the offline store KMS key in Step 3, return to this policy and replace it with the key ARN.

## Step 2: Set up an offline store Amazon S3 bucket in Account B
<a name="feature-store-setup-step2"></a>

Create an Amazon S3 bucket in Account B. If you are using the default `AmazonSageMakerFeatureStoreAccess` policy, the bucket name must include `SageMaker`, `Sagemaker`, or `sagemaker`. Edit the bucket policy as shown in the following example to allow Account A to read and write objects.

This document refers to the following example bucket policy as `Account-B-Offline-Feature-Store-Bucket`. 

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "S3CrossAccountBucketAccess",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetBucketAcl"
            ],
            "Principal": {
                "AWS": [
                    "Account-A-Offline-Feature-Store-Role-ARN"
                ]
            },
            "Resource": [
                "arn:aws:s3:::offline-store-bucket-name/*",
                "arn:aws:s3:::offline-store-bucket-name"
            ]
        }
    ]
}
```

------

In the preceding policy, the principal is `Account-A-Offline-Feature-Store-Role-ARN`, which is the role created in Account A in Step 1 and provided to Amazon SageMaker Feature Store to write to the offline store. You can provide multiple ARN roles under `Principal`.

## Step 3: Set up an offline store AWS KMS encryption key in Account A
<a name="feature-store-setup-step3"></a>

Amazon SageMaker Feature Store ensures that server-side encryption is always enabled for Amazon S3 objects in the offline store. For cross account use cases, you must provide a customer managed key so that you are in control of who can write to the offline store (in this case, `Account-A-Offline-Feature-Store-Role-ARN` from Account A) and who can read from the offline store (in this case, identities from Account B). 

This document refers to the following example key policy as `Account-A-Offline-Feature-Store-KMS-Key-ARN`.

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Id": "key-consolepolicy-3",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                "arn:aws:iam::111122223333:role/Administrator"
                ]
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow Feature Store to get information about the customer managed key",
            "Effect": "Allow",
            "Principal": {
                "Service": "sagemaker.amazonaws.com"
            },
            "Action": [
                "kms:Describe*",
                "kms:Get*",
                "kms:List*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "Account-A-Offline-Feature-Store-Role-ARN",
                    "arn:aws:iam::444455556666:root"
                ]
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:CreateGrant",
                "kms:RetireGrant",
                "kms:ReEncryptFrom",
                "kms:ReEncryptTo",
                "kms:GenerateDataKey",
                "kms:ListAliases",
                "kms:ListGrants"
            ],
            "Resource": "*"
        }
    ]
}
```

------

## Step 4: Create a feature group in Account A
<a name="feature-store-setup-step4"></a>

Next, create the feature group in Account A, with an offline store Amazon S3 bucket in Account B. To do this, provide the following parameters for `RoleArn`, `OfflineStoreConfig.S3StorageConfig.KmsKeyId`, and `OfflineStoreConfig.S3StorageConfig.S3Uri`, respectively: 
+ Provide `Account-A-Offline-Feature-Store-Role-ARN` as the `RoleArn`.
+ Provide `Account-A-Offline-Feature-Store-KMS-Key-ARN` for `OfflineStoreConfig.S3StorageConfig.KmsKeyId`.
+ Provide `Account-B-Offline-Feature-Store-Bucket` for `OfflineStoreConfig.S3StorageConfig.S3Uri`.