

# Cross-account cross-Region account-level subscriptions using Amazon Kinesis Data Streams
<a name="CrossAccountSubscriptions-Kinesis-Account"></a>

When you create a cross-account subscription, you can specify a single account or an organization to be the sender. If you specify an organization, then this procedure enables all accounts in the organization to send logs to the receiver account.

To share log data across accounts, you need to establish a log data sender and receiver:
+ **Log data sender**—gets the destination information from the recipient and lets CloudWatch Logs know that it's ready to send its log events to the specified destination. In the procedures in the rest of this section, the log data sender is shown with a fictional AWS account number of 111111111111.

  If you're going to have multiple accounts in one organization send logs to one recipient account, you can create a policy that grants all accounts in the organization the permission to send logs to the recipient account. You still have to set up separate subscription filters for each sender account.
+ **Log data recipient**—sets up a destination that encapsulates a Amazon Kinesis Data Streams stream and lets CloudWatch Logs know that the recipient wants to receive log data. The recipient then shares the information about this destination with the sender. In the procedures in the rest of this section, the log data recipient is shown with a fictional AWS account number of 999999999999.

To start receiving log events from cross-account users, the log data recipient first creates a CloudWatch Logs destination. Each destination consists of the following key elements:

**Destination name**  
The name of the destination you want to create.

**Target ARN**  
The Amazon Resource Name (ARN) of the AWS resource that you want to use as the destination of the subscription feed.

**Role ARN**  
An AWS Identity and Access Management (IAM) role that grants CloudWatch Logs the necessary permissions to put data into the chosen stream.

**Access policy**  
An IAM policy document (in JSON format, written using IAM policy grammar) that governs the set of users that are allowed to write to your destination.

**Note**  
The log group and the destination must be in the same AWS Region. However, the AWS resource that the destination points to can be located in a different Region. In the examples in the following sections, all Region-specific resources are created in US East (N. Virginia).

**Topics**
+ [Setting up a new cross-account subscription](Cross-Account-Log_Subscription-New-Account.md)
+ [Updating an existing cross-account subscription](Cross-Account-Log_Subscription-Update-Account.md)

# Setting up a new cross-account subscription
<a name="Cross-Account-Log_Subscription-New-Account"></a>

Follow the steps in these sections to set up a new cross-account log subscription.

**Topics**
+ [Step 1: Create a destination](CreateDestination-Account.md)
+ [Step 2: (Only if using an organization) Create an IAM role](CreateSubscriptionFilter-IAMrole-Account.md)
+ [Step 3: Create an account-level subscription filter policy](CreateSubscriptionFilter-Account.md)
+ [Validate the flow of log events](ValidateLogEventFlow-Account.md)
+ [Modify destination membership at runtime](ModifyDestinationMembership-Account.md)

# Step 1: Create a destination
<a name="CreateDestination-Account"></a>

**Important**  
All steps in this procedure are to be done in the log data recipient account.

For this example, the log data recipient account has an AWS account ID of 999999999999, while the log data sender AWS account ID is 111111111111.

 This example creates a destination using a Amazon Kinesis Data Streams stream called RecipientStream, and a role that enables CloudWatch Logs to write data to it. 

When the destination is created, CloudWatch Logs sends a test message to the destination on the recipient account’s behalf. When the subscription filter is active later, CloudWatch Logs sends log events to the destination on the source account’s behalf.

**To create a destination**

1. In the recipient account, create a destination stream in Amazon Kinesis Data Streams. At a command prompt, type:

   ```
   aws kinesis create-stream --stream-name "RecipientStream" --shard-count 1
   ```

1. Wait until the stream becomes active. You can use the **aws kinesis describe-stream** command to check the **StreamDescription.StreamStatus** property. In addition, take note of the **StreamDescription.StreamARN** value because you will pass it to CloudWatch Logs later:

   ```
   aws kinesis describe-stream --stream-name "RecipientStream"
   {
     "StreamDescription": {
       "StreamStatus": "ACTIVE",
       "StreamName": "RecipientStream",
       "StreamARN": "arn:aws:kinesis:us-east-1:999999999999:stream/RecipientStream",
       "Shards": [
         {
           "ShardId": "shardId-000000000000",
           "HashKeyRange": {
             "EndingHashKey": "34028236692093846346337460743176EXAMPLE",
             "StartingHashKey": "0"
           },
           "SequenceNumberRange": {
             "StartingSequenceNumber": "4955113521868881845667950383198145878459135270218EXAMPLE"
           }
         }
       ]
     }
   }
   ```

   It might take a minute or two for your stream to show up in the active state.

1. Create the IAM role that grants CloudWatch Logs the permission to put data into your stream. First, you'll need to create a trust policy in a file **\$1/TrustPolicyForCWL.json**. Use a text editor to create this policy file, do not use the IAM console.

   This policy includes a `aws:SourceArn` global condition context key that specifies the `sourceAccountId` to help prevent the confused deputy security problem. If you don't yet know the source account ID in the first call, we recommend that you put the destination ARN in the source ARN field. In the subsequent calls, you should set the source ARN to be the actual source ARN that you gathered from the first call. For more information, see [Confused deputy prevention](Subscriptions-confused-deputy.md). 

   ```
   {
       "Statement": {
           "Effect": "Allow",
           "Principal": {
               "Service": "logs.amazonaws.com"
           },
           "Condition": {
               "StringLike": {
                   "aws:SourceArn": [
                       "arn:aws:logs:region:sourceAccountId:*",
                       "arn:aws:logs:region:recipientAccountId:*"
                   ]
               }
           },
           "Action": "sts:AssumeRole"
       }
   }
   ```

1. Use the **aws iam create-role** command to create the IAM role, specifying the trust policy file. Take note of the returned Role.Arn value because it will also be passed to CloudWatch Logs later:

   ```
   aws iam create-role \
   --role-name CWLtoKinesisRole \
   --assume-role-policy-document file://~/TrustPolicyForCWL.json
   
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Condition": {
                       "StringLike": {
                           "aws:SourceArn": [
                               "arn:aws:logs:region:sourceAccountId:*",
                               "arn:aws:logs:region:recipientAccountId:*"
                           ]
                       }
                   },
                   "Principal": {
                       "Service": "logs.amazonaws.com"
                   }
               }
           },
           "RoleId": "AAOIIAH450GAB4HC5F431",
           "CreateDate": "2023-05-29T13:46:29.431Z",
           "RoleName": "CWLtoKinesisRole",
           "Path": "/",
           "Arn": "arn:aws:iam::999999999999:role/CWLtoKinesisRole"
       }
   }
   ```

1. Create a permissions policy to define which actions CloudWatch Logs can perform on your account. First, use a text editor to create a permissions policy in a file **\$1/PermissionsForCWL.json**:

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "kinesis:PutRecord",
         "Resource": "arn:aws:kinesis:region:999999999999:stream/RecipientStream"
       }
     ]
   }
   ```

1. Associate the permissions policy with the role by using the **aws iam put-role-policy** command:

   ```
   aws iam put-role-policy \
       --role-name CWLtoKinesisRole \
       --policy-name Permissions-Policy-For-CWL \
       --policy-document file://~/PermissionsForCWL.json
   ```

1. After the stream is in the active state and you have created the IAM role, you can create the CloudWatch Logs destination.

   1. This step doesn't associate an access policy with your destination and is only the first step out of two that completes a destination creation. Make a note of the **DestinationArn** that is returned in the payload:

      ```
      aws logs put-destination \
          --destination-name "testDestination" \
          --target-arn "arn:aws:kinesis:region:999999999999:stream/RecipientStream" \
          --role-arn "arn:aws:iam::999999999999:role/CWLtoKinesisRole"
      
      {
        "DestinationName" : "testDestination",
        "RoleArn" : "arn:aws:iam::999999999999:role/CWLtoKinesisRole",
        "DestinationArn" : "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
        "TargetArn" : "arn:aws:kinesis:us-east-1:999999999999:stream/RecipientStream"
      }
      ```

   1. After step 7a is complete, in the log data recipient account, associate an access policy with the destination. This policy must specify the **logs:PutSubscriptionFilter** action and grants permission to the sender account to access the destination.

      The policy grants permission to the AWS account that sends logs. You can specify just this one account in the policy, or if the sender account is a member of an organization, the policy can specify the organization ID of the organization. This way, you can create just one policy to allow multiple accounts in one organization to send logs to this destination account.

      Use a text editor to create a file named `~/AccessPolicy.json` with one of the following policy statements.

      This first example policy allows all accounts in the organization that have an ID of `o-1234567890` to send logs to the recipient account.

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

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "",
                  "Effect": "Allow",
                  "Principal": "*",
                  "Action": [
                      "logs:PutSubscriptionFilter",
                      "logs:PutAccountPolicy"
                  ],
                  "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
                  "Condition": {
                      "StringEquals": {
                          "aws:PrincipalOrgID": [
                              "o-1234567890"
                          ]
                      }
                  }
              }
          ]
      }
      ```

------

      This next example allows just the log data sender account (111111111111) to send logs to the log data recipient account.

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

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "",
                  "Effect": "Allow",
                  "Principal": {
                      "AWS": "111111111111"
                  },
                  "Action": [
                      "logs:PutSubscriptionFilter",
                      "logs:PutAccountPolicy"
                  ],
                  "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination"
              }
          ]
      }
      ```

------

   1. Attach the policy you created in the previous step to the destination.

      ```
      aws logs put-destination-policy \
          --destination-name "testDestination" \
          --access-policy file://~/AccessPolicy.json
      ```

      This access policy enables users in the AWS Account with ID 111111111111 to call **PutSubscriptionFilter** against the destination with ARN arn:aws:logs:*region*:999999999999:destination:testDestination. Any other user's attempt to call PutSubscriptionFilter against this destination will be rejected.

      To validate a user's privileges against an access policy, see [Using Policy Validator](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies_policy-validator.html) in the *IAM User Guide*.

When you have finished, if you're using AWS Organizations for your cross-account permissions, follow the steps in [Step 2: (Only if using an organization) Create an IAM role](CreateSubscriptionFilter-IAMrole-Account.md). If you're granting permissions directly to the other account instead of using Organizations, you can skip that step and proceed to [Step 3: Create an account-level subscription filter policy](CreateSubscriptionFilter-Account.md).

# Step 2: (Only if using an organization) Create an IAM role
<a name="CreateSubscriptionFilter-IAMrole-Account"></a>

In the previous section, if you created the destination by using an access policy that grants permissions to the organization that account `111111111111` is in, instead of granting permissions directly to account `111111111111`, then follow the steps in this section. Otherwise, you can skip to [Step 3: Create an account-level subscription filter policy](CreateSubscriptionFilter-Account.md).

The steps in this section create an IAM role, which CloudWatch can assume and validate whether the sender account has permission to create a subscription filter against the recipient destination. 

Perform the steps in this section in the sender account. The role must exist in the sender account, and you specify the ARN of this role in the subscription filter. In this example, the sender account is `111111111111`.

**To create the IAM role necessary for cross-account log subscriptions using AWS Organizations**

1. Create the following trust policy in a file `/TrustPolicyForCWLSubscriptionFilter.json`. Use a text editor to create this policy file; do not use the IAM console.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole"
     }
   }
   ```

1. Create the IAM role that uses this policy. Take note of the `Arn` value that is returned by the command, you will need it later in this procedure. In this example, we use `CWLtoSubscriptionFilterRole` for the name of the role we're creating.

   ```
   aws iam create-role \ 
        --role-name CWLtoSubscriptionFilterRole \ 
        --assume-role-policy-document file://~/TrustPolicyForCWLSubscriptionFilter.json
   ```

1. Create a permissions policy to define the actions that CloudWatch Logs can perform on your account.

   1. First, use a text editor to create the following permissions policy in a file named `~/PermissionsForCWLSubscriptionFilter.json`.

      ```
      { 
          "Statement": [ 
              { 
                  "Effect": "Allow", 
                  "Action": "logs:PutLogEvents", 
                  "Resource": "arn:aws:logs:region:111111111111:log-group:LogGroupOnWhichSubscriptionFilterIsCreated:*" 
              } 
          ] 
      }
      ```

   1. Enter the following command to associate the permissions policy you just created with the role that you created in step 2.

      ```
      aws iam put-role-policy  
          --role-name CWLtoSubscriptionFilterRole  
          --policy-name Permissions-Policy-For-CWL-Subscription-filter 
          --policy-document file://~/PermissionsForCWLSubscriptionFilter.json
      ```

When you have finished, you can proceed to [Step 3: Create an account-level subscription filter policy](CreateSubscriptionFilter-Account.md).

# Step 3: Create an account-level subscription filter policy
<a name="CreateSubscriptionFilter-Account"></a>

After you create a destination, the log data recipient account can share the destination ARN (arn:aws:logs:us-east-1:999999999999:destination:testDestination) with other AWS accounts so that they can send log events to the same destination. These other sending accounts users then create a subscription filter on their respective log groups against this destination. The subscription filter immediately starts the flow of real-time log data from the chosen log group to the specified destination.

**Note**  
If you are granting permissions for the subscription filter to an entire organization, you will need to use the ARN of the IAM role that you created in [Step 2: (Only if using an organization) Create an IAM role](CreateSubscriptionFilter-IAMrole-Account.md).

In the following example, an account-level subscription filter policy is created in a sending account. the filter is associated with the sender account `111111111111` so that every log event matching the filter and selection criteria is delivered to the destination you previously created. That destination encapsulates a stream called "RecipientStream".

The `selection-criteria` field is optional, but is important for excluding log groups that can cause an infinite log recursion from a subscription filter. For more information about this issue and determining which log groups to exclude, see [Log recursion prevention](Subscriptions-recursion-prevention.md). Currently, NOT IN is the only supported operator for `selection-criteria`.

```
aws logs put-account-policy \
    --policy-name "CrossAccountStreamsExamplePolicy" \
    --policy-type "SUBSCRIPTION_FILTER_POLICY" \
    --policy-document '{"DestinationArn":"arn:aws:logs:region:999999999999:destination:testDestination", "FilterPattern": "", "Distribution": "Random"}' \
    --selection-criteria 'LogGroupName NOT IN ["LogGroupToExclude1", "LogGroupToExclude2"]' \
    --scope "ALL"
```

The sender account's log groups and the destination must be in the same AWS Region. However, the destination can point to an AWS resource such as a Amazon Kinesis Data Streams stream that is located in a different Region.

# Validate the flow of log events
<a name="ValidateLogEventFlow-Account"></a>

After you create the account-level subscription filter policy, CloudWatch Logs forwards all the incoming log events that match the filter pattern and selection criteria to the stream that is encapsulated within the destination stream called "**RecipientStream**". The destination owner can verify that this is happening by using the **aws kinesis get-shard-iterator** command to grab a Amazon Kinesis Data Streams shard, and using the **aws kinesis get-records** command to fetch some Amazon Kinesis Data Streams records:

```
aws kinesis get-shard-iterator \
      --stream-name RecipientStream \
      --shard-id shardId-000000000000 \
      --shard-iterator-type TRIM_HORIZON

{
    "ShardIterator":
    "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiKEXAMPLE"
}

aws kinesis get-records \
      --limit 10 \
      --shard-iterator
      "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiKEXAMPLE"
```

**Note**  
You might need to rerun the `get-records` command a few times before Amazon Kinesis Data Streams starts to return data.

You should see a response with an array of Amazon Kinesis Data Streams records. The data attribute in the Amazon Kinesis Data Streams record is compressed in gzip format and then base64 encoded. You can examine the raw data from the command line using the following Unix command:

```
echo -n "<Content of Data>" | base64 -d | zcat
```

The base64 decoded and decompressed data is formatted as JSON with the following structure:

```
{
    "owner": "111111111111",
    "logGroup": "CloudTrail/logs",
    "logStream": "111111111111_CloudTrail/logs_us-east-1",
    "subscriptionFilters": [
        "RecipientStream"
    ],
    "messageType": "DATA_MESSAGE",
    "logEvents": [
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        },
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        },
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        }
    ]
}
```

The key elements in the data structure are the following:

**messageType**  
Data messages will use the "DATA\$1MESSAGE" type. Sometimes CloudWatch Logs might emit Amazon Kinesis Data Streams records with a "CONTROL\$1MESSAGE" type, mainly for checking if the destination is reachable.

**owner**  
The AWS Account ID of the originating log data.

**logGroup**  
The log group name of the originating log data.

**logStream**  
The log stream name of the originating log data.

**subscriptionFilters**  
The list of subscription filter names that matched with the originating log data.

**logEvents**  
The actual log data, represented as an array of log event records. The "id" property is a unique identifier for every log event.

**policyLevel**  
The level at which the policy was enforced. "ACCOUNT\$1LEVEL\$1POLICY" is the `policyLevel` for an account-level subscription filter policy.

# Modify destination membership at runtime
<a name="ModifyDestinationMembership-Account"></a>

You might encounter situations where you have to add or remove membership of some users from a destination that you own. You can use the `put-destination-policy` command on your destination with a new access policy. In the following example, a previously added account **111111111111** is stopped from sending any more log data, and account **222222222222** is enabled.

1. Fetch the policy that is currently associated with the destination **testDestination** and make a note of the **AccessPolicy**:

   ```
   aws logs describe-destinations \
       --destination-name-prefix "testDestination"
   
   {
    "Destinations": [
      {
        "DestinationName": "testDestination",
        "RoleArn": "arn:aws:iam::999999999999:role/CWLtoKinesisRole",
        "DestinationArn": "arn:aws:logs:region:999999999999:destination:testDestination",
        "TargetArn": "arn:aws:kinesis:region:999999999999:stream/RecipientStream",
        "AccessPolicy": "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Sid\": \"\", \"Effect\": \"Allow\", \"Principal\": {\"AWS\": \"111111111111\"}, \"Action\": \"logs:PutSubscriptionFilter\", \"Resource\": \"arn:aws:logs:region:999999999999:destination:testDestination\"}] }"
      }
    ]
   }
   ```

1. Update the policy to reflect that account **111111111111** is stopped, and that account **222222222222** is enabled. Put this policy in the **\$1/NewAccessPolicy.json** file:

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "222222222222"
               },
               "Action": [
                   "logs:PutSubscriptionFilter",
                   "logs:PutAccountPolicy"
               ],
               "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination"
           }
       ]
   }
   ```

------

1. Call **PutDestinationPolicy** to associate the policy defined in the **NewAccessPolicy.json** file with the destination:

   ```
   aws logs put-destination-policy \
   --destination-name "testDestination" \
   --access-policy file://~/NewAccessPolicy.json
   ```

   This will eventually disable the log events from account ID **111111111111**. Log events from account ID **222222222222** start flowing to the destination as soon as the owner of account **222222222222** creates a subscription filter.

# Updating an existing cross-account subscription
<a name="Cross-Account-Log_Subscription-Update-Account"></a>

If you currently have a cross-account logs subscription where the destination account grants permissions only to specific sender accounts, and you want to update this subscription so that the destination account grants access to all accounts in an organization, follow the steps in this section.

**Topics**
+ [Step 1: Update the subscription filters](Cross-Account-Log_Subscription-Update-filter-Account.md)
+ [Step 2: Update the existing destination access policy](Cross-Account-Log_Subscription-Update-policy-Account.md)

# Step 1: Update the subscription filters
<a name="Cross-Account-Log_Subscription-Update-filter-Account"></a>

**Note**  
This step is needed only for cross-account subscriptions for logs that are created by the services listed in [Enable logging from AWS services](AWS-logs-and-resource-policy.md). If you are not working with logs created by one of these log groups, you can skip to [Step 2: Update the existing destination access policy](Cross-Account-Log_Subscription-Update-policy-Account.md).

In certain cases, you must update the subscription filters in all the sender accounts that are sending logs to the destination account. The update adds an IAM role, which CloudWatch can assume and validate that the sender account has permission to send logs to the recipient account.

Follow the steps in this section for every sender account that you want to update to use organization ID for the cross-account subscription permissions.

In the examples in this section, two accounts, `111111111111` and `222222222222` already have subscription filters created to send logs to account `999999999999`. The existing subscription filter values are as follows:

```
## Existing Subscription Filter parameter values
{
    "DestinationArn": "arn:aws:logs:region:999999999999:destination:testDestination",
    "FilterPattern": "{$.userIdentity.type = Root}",
    "Distribution": "Random"
}
```

If you need to find the current subscription filter parameter values, enter the following command.

```
aws logs describe-account-policies \
--policy-type "SUBSCRIPTION_FILTER_POLICY" \
--policy-name "CrossAccountStreamsExamplePolicy"
```

**To update a subscription filter to start using organization IDs for cross-account log permissions**

1. Create the following trust policy in a file `~/TrustPolicyForCWL.json`. Use a text editor to create this policy file; do not use the IAM console.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole"
     }
   }
   ```

1. Create the IAM role that uses this policy. Take note of the `Arn` value of the `Arn` value that is returned by the command, you will need it later in this procedure. In this example, we use `CWLtoSubscriptionFilterRole` for the name of the role we're creating.

   ```
   aws iam create-role 
       \ --role-name CWLtoSubscriptionFilterRole 
       \ --assume-role-policy-document file://~/TrustPolicyForCWL.json
   ```

1. Create a permissions policy to define the actions that CloudWatch Logs can perform on your account.

   1. First, use a text editor to create the following permissions policy in a file named `/PermissionsForCWLSubscriptionFilter.json`.

      ```
      { 
          "Statement": [ 
              { 
                  "Effect": "Allow", 
                  "Action": "logs:PutLogEvents", 
                  "Resource": "arn:aws:logs:region:111111111111:log-group:LogGroupOnWhichSubscriptionFilterIsCreated:*" 
              } 
          ] 
      }
      ```

   1. Enter the following command to associate the permissions policy you just created with the role that you created in step 2.

      ```
      aws iam put-role-policy 
          --role-name CWLtoSubscriptionFilterRole 
          --policy-name Permissions-Policy-For-CWL-Subscription-filter 
          --policy-document file://~/PermissionsForCWLSubscriptionFilter.json
      ```

1. Enter the following command to update the subscription filter policy.

   ```
   aws logs put-account-policy \
       --policy-name "CrossAccountStreamsExamplePolicy" \
       --policy-type "SUBSCRIPTION_FILTER_POLICY" \
       --policy-document '{"DestinationArn":"arn:aws:logs:region:999999999999:destination:testDestination", "FilterPattern": "{$.userIdentity.type = Root}", "Distribution": "Random"}' \
       --selection-criteria 'LogGroupName NOT IN ["LogGroupToExclude1", "LogGroupToExclude2"]' \
       --scope "ALL"
   ```

# Step 2: Update the existing destination access policy
<a name="Cross-Account-Log_Subscription-Update-policy-Account"></a>

After you have updated the subscription filters in all of the sender accounts, you can update the destination access policy in the recipient account.

In the following examples, the recipient account is `999999999999` and the destination is named `testDestination`.

The update enables all accounts that are part of the organization with ID `o-1234567890` to send logs to the recipient account. Only the accounts that have subscription filters created will actually send logs to the recipient account.

**To update the destination access policy in the recipient account to start using an organization ID for permissions**

1. In the recipient account, use a text editor to create a `~/AccessPolicy.json` file with the following contents.

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": "*",
               "Action": [
                   "logs:PutSubscriptionFilter",
                   "logs:PutAccountPolicy"
               ],
               "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
               "Condition": {
                   "StringEquals": {
                       "aws:PrincipalOrgID": [
                           "o-1234567890"
                       ]
                   }
               }
           }
       ]
   }
   ```

------

1. Enter the following command to attach the policy that you just created to the existing destination. To update a destination to use an access policy with an organization ID instead of an access policy that lists specific AWS account IDs, include the `force` parameter.
**Warning**  
If you are working with logs sent by an AWS service listed in [Enable logging from AWS services](AWS-logs-and-resource-policy.md), then before doing this step, you must have first updated the subscription filters in all the sender accounts as explained in [Step 1: Update the subscription filters](Cross-Account-Log_Subscription-Update-filter-Account.md).

   ```
   aws logs put-destination-policy 
       \ --destination-name "testDestination" 
       \ --access-policy file://~/AccessPolicy.json
       \ --force
   ```