diff --git a/website/content/docs/commands/policies/create.mdx b/website/content/docs/commands/policies/create.mdx new file mode 100644 index 000000000..0fae2876d --- /dev/null +++ b/website/content/docs/commands/policies/create.mdx @@ -0,0 +1,61 @@ +--- +layout: docs +page_title: policies create - Command +description: |- + The "policies create" command lets you create Boundary policies. +--- + +# policies create + +This feature requires HCP Boundary or Boundary Enterprise + +Command: `boundary policies create` + +The `boundary policies create` command lets you create Boundary policies. + +Storage policies codify how long session recordings must be kept and when they should be deleted. +For more information, refer to the [storage policies](/boundary/docs/concepts/domain-model/storage-policy) documentation. + +## Example + +This example creates a storage policy with the name `prod` and the description `Prod Storage Policy`. +The policy has a retention period of 10 days, and it will be deleted after 20 days: + +```shell-session +$ boundary policies create storage -name prod -description "Prod Storage Policy" -retain-for-days 10 -delete-after-days 20 +``` + +## Usage + + + +```shell-session +$ boundary policies create storage [options] [args] +``` + + + +### Subcommands + +- `storage` - Creates a storage type policy. + +### Command options + +- `-description=` - The description to set for the policy. +- `-name=` -The name to set on the policy. +The name is optional, but if you set it, it must be unique within the scope ID. +If you do not provide a name, Boundary uses the storage policy ID as the default name. +- `-scope-id=` - Scope in which to create the policy. +The default scope is global. +You can also specify a scope using the **BOUNDARY_SCOPE_ID** environment variable. + +### Storage policy options + +- `-delete-after-days=` - The number of days after which Boundary will delete a session recording. +- `-delete-after-overridable=` - Whether the policy's deletion period can be overridden by downstream policies. +The value can be `true` or `false`. +- `-retain-for-days=` - The number of days a session recording should be retained for. +- `-retain-for-overridable=` - Whether the policy's retention period can be overriden by downstream storage policies. +The value can be `true` or `false`. + +@include 'cmd-option-note.mdx' \ No newline at end of file diff --git a/website/content/docs/commands/policies/delete.mdx b/website/content/docs/commands/policies/delete.mdx new file mode 100644 index 000000000..c6d5ab559 --- /dev/null +++ b/website/content/docs/commands/policies/delete.mdx @@ -0,0 +1,38 @@ +--- +layout: docs +page_title: policies delete - Command +description: |- + The "policies delete" command lets you delete Boundary policies. +--- + +# policies delete + +This feature requires HCP Boundary or Boundary Enterprise + +Command: `boundary policies delete` + +The `boundary policies delete` command lets you delete Boundary policies. + +## Example + +This example deletes a policy with the ID `p_1234567890`: + +```shell-session +$ boundary policies delete -id p_1234567890 +``` + +## Usage + + + +```shell-session +$ boundary policies delete [options] [args] +``` + + + +### Command options + +- `-id=` - The ID of the policy you want to delete. + +@include 'cmd-option-note.mdx' \ No newline at end of file diff --git a/website/content/docs/commands/policies/index.mdx b/website/content/docs/commands/policies/index.mdx new file mode 100644 index 000000000..c858c9703 --- /dev/null +++ b/website/content/docs/commands/policies/index.mdx @@ -0,0 +1,51 @@ +--- +layout: docs +page_title: policies - Command +description: |- + The "policies" command lets you perform operations on Boundary policy resources. +--- + +# policies + +This feature requires HCP Boundary or Boundary Enterprise + +Command: `boundary policies` + +The `policies` command lets you perform operations on Boundary policies. + +Storage policies codify how long session recordings must be kept and when they should be deleted. +For more information, refer to the [storage policies](/boundary/docs/concepts/domain-model/storage-policy) documentation. + +## Example + +The following command reads a policy with the id `pst_1234567890`: + +```shell-session +$ boundary policies read -id chr_1234567890 +``` + +## Usage + + + +```shell-session +Usage: boundary policies [options] [args] + # ... +Subcommands: + create Create a policy + delete Delete a policy + list List a policy + read Read a policy + update Update a policy +``` + + + +For more information, examples, and usage, click on the name +of the subcommand in the sidebar or one of the links below: + +- [create](/boundary/docs/commands/policies/create) +- [delete](/boundary/docs/commands/policies/delete) +- [list](/boundary/docs/commands/policies/list) +- [read](/boundary/docs/commands/policies/read) +- [update](/boundary/docs/commands/policies/update) \ No newline at end of file diff --git a/website/content/docs/commands/policies/list.mdx b/website/content/docs/commands/policies/list.mdx new file mode 100644 index 000000000..b2bd9b1a3 --- /dev/null +++ b/website/content/docs/commands/policies/list.mdx @@ -0,0 +1,47 @@ +--- +layout: docs +page_title: policies list - Command +description: |- + The "policies list" command lists the policies within a given scope or resource. +--- + +# policies list + +This feature requires HCP Boundary or Boundary Enterprise + +Command: `policies list` + +The `policies list` command lets you list the policies within a given scope or resource. + +## Example + +This example lists all policies within the scope `s_1234567890`. +The `recursive` option means Boundary runs the operation recursively on any child scopes, if applicable: + +```shell-session +$ boundary policies list -scope-id s_1234567890 -recursive +``` + +## Usage + + + +```shell-session +$ boundary policies list [options] [args] +``` + + + +### Command options + +- `-filter=` - If set, Boundary filters the list operation before the results are returned. +The filter operates against each item in the list. +We recommend that you use single quotes, because the filters contain double quotes. +Refer to the [Filter resource listings documentation](/boundary/docs/concepts/filtering/resource-listing) for more details. +- `recursive` - If set, runs the list operation recursively on any child scopes, if the type supports it. +The default value is `false`. +- `scope-id=` - The scope from which to list policies. +The default value is `global`. +You can also specify this value using the **BOUNDARY_SCOPE_ID** environment variable. + +@include 'cmd-option-note.mdx' \ No newline at end of file diff --git a/website/content/docs/commands/policies/read.mdx b/website/content/docs/commands/policies/read.mdx new file mode 100644 index 000000000..7aacfcb23 --- /dev/null +++ b/website/content/docs/commands/policies/read.mdx @@ -0,0 +1,38 @@ +--- +layout: docs +page_title: policies read - Command +description: |- + The "policies read" command lets you read information about Boundary policies. +--- + +# policies read + +This feature requires HCP Boundary or Boundary Enterprise + +Command: `boundary policies read` + +The `boundary policies read` command lets you read information about Boundary policies. + +## Example + +This example reads the details of a policy with the ID `p_1234567890`: + +```shell-session +$ boundary policies read -id p_1234567890 +``` + +## Usage + + + +```shell-session +$ boundary policies read [options] [args] +``` + + + +### Command options + +- `-id=` - The ID of the policy you want to read. + +@include 'cmd-option-note.mdx' \ No newline at end of file diff --git a/website/content/docs/commands/policies/update.mdx b/website/content/docs/commands/policies/update.mdx new file mode 100644 index 000000000..ab6564c74 --- /dev/null +++ b/website/content/docs/commands/policies/update.mdx @@ -0,0 +1,61 @@ +--- +layout: docs +page_title: policies update - Command +description: |- + The "policies update" command lets you update Boundary policies. +--- + +# policies update + +This feature requires HCP Boundary or Boundary Enterprise + +Command: `boundary policies update` + +The `boundary policies update` command lets you update Boundary policies. + +Storage policies codify how long session recordings must be kept and when they should be deleted. +For more information, refer to the [storage policies](/boundary/docs/concepts/domain-model/storage-policy) documentation. + +## Example + +This example updates a storage policy with the ID `pst_1234567890` to add the name `dev` and the description `Dev Storage Policy`. +The policy has a retention period of 1 day, and it will be deleted after 2 days: + +```shell-session +$ boundary policies update storage -id pst_1234567890 -name dev -description "Dev Storage Policy" -retain-for-days 1 -delete-after-days 2 +``` + +## Usage + + + +```shell-session +$ boundary policies update storage [options] [args] +``` + + + +### Subcommands + +- `storage` - Updates a storage type policy. + +### Command options + +- `-description=` - The description to set for the policy. +- `-id=` - The ID of the policy you want to update. +- `-name=` -The name to set on the policy. +The name is optional, but if you set it, it must be unique within the scope ID. +If you do not provide a name, Boundary uses the storage policy ID as the default name. +- `-version=` - The version of the policy to update. +If you do not specify a version, the command performs a check-and-set automatically. + +### Storage policy options + +- `-delete-after-days=` - The number of days after which Boundary will delete a session recording. +- `-delete-after-overridable=` - Whether the policy's deletion period can be overridden by downstream policies. +The value can be `true` or `false`. +- `-retain-for-days=` - The number of days a session recording should be retained for. +- `-retain-for-overridable=` - Whether the policy's retention period can be overriden by downstream storage policies. +The value can be `true` or `false`. + +@include 'cmd-option-note.mdx' \ No newline at end of file diff --git a/website/content/docs/concepts/domain-model/scopes.mdx b/website/content/docs/concepts/domain-model/scopes.mdx index 9bd844105..134fd4eb6 100644 --- a/website/content/docs/concepts/domain-model/scopes.mdx +++ b/website/content/docs/concepts/domain-model/scopes.mdx @@ -67,13 +67,22 @@ A scope has the following configurable attributes: - `description` - (optional) +## Storage policy association + +This feature requires HCP Boundary or Boundary Enterprise + +[Storage policies][] that are created in the global scope can be associated with any org scope. +However, a storage policy created in an org scope can only be associated with that org scope. +Changing the storage policy assigned to a scope can impact the resultant set of policy, but such a change only affects future recordings that you create within that scope or using that storage policy. + ## Referenced by -- [Auth Method][] -- [Credential Store][] +- [Auth method][] +- [Credential store][] - [Group][] -- [Host Catalog][] +- [Host catalog][] - [Role][] +- [Storage policies][] - [Target][] - [User][] @@ -94,6 +103,7 @@ A scope has the following configurable attributes: [projects]: /boundary/docs/concepts/domain-model/scopes#projects [role]: /boundary/docs/concepts/domain-model/roles [roles]: /boundary/docs/concepts/domain-model/roles +[storage policies]: /boundary/docs/concepts/domain-model/storage-policy [target]: /boundary/docs/concepts/domain-model/targets [targets]: /boundary/docs/concepts/domain-model/targets [user]: /boundary/docs/concepts/domain-model/users diff --git a/website/content/docs/concepts/domain-model/session-recordings.mdx b/website/content/docs/concepts/domain-model/session-recordings.mdx index 6a09ca45e..d0f00eb60 100644 --- a/website/content/docs/concepts/domain-model/session-recordings.mdx +++ b/website/content/docs/concepts/domain-model/session-recordings.mdx @@ -2,7 +2,7 @@ layout: docs page_title: Domain model - session recordings description: |- - The anatomy of a Boundary session recording + Use session recordings to audit user sessions in Boundary. Learn how to configure session recordings to monitor usage. --- # Session recordings @@ -45,9 +45,58 @@ A session recording belongs to the scope of the [storage bucket][] it is stored in. The scope can be either the global scope or an [organization][] scope. -## Referenced by +## Resultant set of policy calculation -- [Storage Bucket][] +[Storage policies][] codify how long session recordings must be kept and when they should be deleted. +The resultant set of policy (RSoP) refers to the set of policy attributes that apply to a resource. +When you apply policies on multiple levels, the results can conflict. +Boundary evaluates each storage policy attribute individually, starting at the global scope and then evaluating any storage policies assigned to org scopes. + +In accordance with the RSoP, Boundary considers the following principles in order: + +1. Retention wins over deletion. The retention duration parameter guarantees that a session recording is retained for at least that duration. Before the retention duration has transpired, manual deletes will fail and Boundary will not attempt to automatically delete any session recordings. +2. Longest retention wins. When Boundary evaluates multiple storage policies, the longer retention duration parameter applies to the session recording. +3. The shortest deletion wins. When Boundary evaluates multiple storage policies, the shorter delete after duration parameter applies to the session recording. + +Each storage policy attribute also indicates whether the attribute can be overridden or not. +If the attribute cannot be overridden, Boundary stops evaluating the RSoP for that attribute at lower scopes. + +Changing the policy assigned to a scope or changing an attribute of a storage policy can impact the RSoP. +Such a change only affects future session recordings created in that scope or using that storage policy. +If a session recording is not in compliance with the current RSoP, the session recording API indicates that it is out of compliance with the current policy. + +### Examples + +In the following examples, Boundary determines the resultant set of policies using the `retain_for_days_overridable` and `delete_after_days_overridable` attributes. +A value of `true` indicates the number of days can be overridden, while a value of `false` indicates that it cannot be overridden. + +#### Example 1 +In this case, the retention value is derived from the org policy and the deletion value is derived from the global policy. + +| | Global policy | Org policy | Result policy | +| ------------------------------ | ------------- | ---------- | ------------- | +| Retain for days (Overridable) | 10 (True) | 20 (True) | 20 | +| Delete after days (Overridable) | 30 (True) | 40 (True) | 30 | + +#### Example 2 +In this case, Boundary ignores the org policy values because the global policy values are not overridable. + +| | Global policy | Org policy | Result policy | +| ------------------------------ | ------------- | ---------- | ------------- | +| Retain for days (Overridable) | 10 (False) | 20 (True) | 10 | +| Delete after days (Overridable) | 30 (False) | 40 (True) | 30 | + +#### Example 3 +In this case, the longest retention value is 30, and the shortest deletion value is 20. +However, the `delete_after_days` value cannot be less than the `retain_for_days` value. +Therefore, Boundary sets the deletion value to the retention value. + +| | Global policy | Org policy | Result policy | +| ------------------------------ | ------------- | ---------- | ------------- | +| Retain for days (Overridable) | 30 (True) | 20 (True) | 30 | +| Delete after days (Overridable) | 50 (True) | 20 (True) | 30 | + +For more information, refer to the [storage policy attributes](/boundary/docs/concepts/domain-model/storage-policy#attributes) documentation. ## Service API docs @@ -64,4 +113,5 @@ The following services are relevant to this resource: [user]: /boundary/docs/concepts/domain-model/users [organization]: /boundary/docs/concepts/domain-model/scopes#organizations [session]: /boundary/docs/concepts/domain-model/sessions -[storage bucket]: /boundary/docs/concepts/domain-model/storage-buckets \ No newline at end of file +[storage bucket]: /boundary/docs/concepts/domain-model/storage-buckets +[storage policies]: /boundary/docs/concepts/domain-model/storage-policy \ No newline at end of file diff --git a/website/content/docs/concepts/domain-model/storage-policy.mdx b/website/content/docs/concepts/domain-model/storage-policy.mdx new file mode 100644 index 000000000..5729d8848 --- /dev/null +++ b/website/content/docs/concepts/domain-model/storage-policy.mdx @@ -0,0 +1,59 @@ +--- +layout: docs +page_title: Domain model - storage policies +description: |- + Use storage policies to manage session recording retention in Boundary. Learn how to configure policies for global and org scopes, and specify retention periods. +--- + +# Storage policies + +This feature requires HCP Boundary or Boundary Enterprise + +A resource known as a storage policy is used to codify how long [session recordings][] must be kept and when they should be deleted. +A storage policy's name is optional, but it must be unique if you define one. +Storage policies can only be assigned to the global [scope][] or an org scope. + +A storage policy exists in either the global scope or an org scope. +Storage policies that are created in the global scope can be associated with any org scope. +However, a storage policy created in an org scope can only be associated with that org scope. +Any storage policies associated with an org scope are deleted when you delete the org itself. + +## Attributes + +A storage policy has the following configurable attributes: + +- `name` - (Optional) The name of the resource in Boundary. +The name is optional, but if you set it, it must be unique within the scope ID. +If you do not provide a name, Boundary uses the storage policy ID as the default name. +- `description` - (Optional) A description of the resource. +- `retain_for_days` - (Optional) The number of days a session recording must be kept. +A value of `-1` indicates an infinite retention. +- `retain_for_days_overridable` - (Optional) Indicates that a lower scope can override the `retain_for_days` attribute value. +The default value is `true`. +- `delete_after_days` - (Optional) The number of days after which a session recording should be deleted. +- `delete_after_days_overridable` - (Optional) Indicates that a lower scope can override the `delete_after_days` attribute value. +The default value is `true`. + +## Retention and deletion guidelines + +- Setting the `retain_for_days` value to `-1` (infinity) requires the `delete_after_days` value to be set to `0`. +- If you set the `delete_after_days` value, it must be greater than or equal to 0. +- The `delete_after_days` value must be greater than or equal to the `retain_for_days` value, unless you set `delete_after_days` to `0`. +- You cannot set the `retain_for_days` and `delete_after_days` values to 0. +- Changing an attribute of a storage policy that is assigned to a scope can impact the resultant set of policy. +However, such a change only affects future recordings created within that scope or using that storage policy. + +## Referenced by + +- [scopes](/boundary/docs/concepts/domain-model/scopes) +- [session recordings](/boundary/docs/concepts/domain-model/session-recordings) + +## Service API docs + +The following services are relevant to this resource: + +- [Scope Service](/boundary/api-docs/scope-service) +- [Policy Service](/boundary/api-docs/policy-service) + +[session recordings]: /boundary/docs/concepts/domain-model/session-recordings +[scope]: /boundary/docs/concepts/domain-model/scopes \ No newline at end of file diff --git a/website/content/docs/configuration/session-recording/configure-storage-policy.mdx b/website/content/docs/configuration/session-recording/configure-storage-policy.mdx new file mode 100644 index 000000000..9acf1ce54 --- /dev/null +++ b/website/content/docs/configuration/session-recording/configure-storage-policy.mdx @@ -0,0 +1,670 @@ +--- +layout: docs +page_title: Configure storage bucket policies +description: |- + How to configure storage bucket lifecycle policies for session recording in Boundary +--- + +# Configure storage bucket policies + +This feature requires HCP Boundary or Boundary Enterprise + +As of Boundary 0.15.0, retention policies can codify storage bucket lifecycle management for [session recordings][]. +A Boundary resource known as a [storage bucket][] is used to store recorded sessions. +A resource known as a [storage policy][] is used to codify how long session recordings must be kept and when they should be deleted. + +A storage policy exists in either the global scope or an org scope. +Storage policies that are created in the global scope can be associated with any org scope. +However, a storage policy created in an org scope can only be associated with that org scope. +Any storage policies associated with an org scope are deleted when you delete the org itself. + +For more information about using session recording to audit user sessions, refer to [Auditing](/boundary/docs/concepts/auditing). + +## Requirements + +Before you can create a storage bucket in Boundary, you must ensure that your environment meets certain requirements. +Session recording requires specific configuration for both the external store and the Boundary worker. +At this time, the only supported storage is AWS S3. + +A Boundary worker configured for local storage is also required to set up session recording and configure recording bucket policies. + +Refer to [Create a storage bucket](/boundary/docs/configuration/session-recording/create-storage-bucket) to learn more about setting up storage for session recordings. + +## Example storage policies + +A storage policy defines how long the recording within a scope should retain its session recordings. Storage policy examples include: + +- Keep forever +- Do not delete +- Do not retain +- Custom retention period + +## Create a storage policy + +Complete the following steps to create a storage policy in Boundary for session recording: + + + + +1. Log in to Boundary. +1. Select **Storage Policies** in the navigation panel in the `global` scope. +1. Click **Create a new storage policy**. +1. Complete the following fields to create the Boundary storage policy: + - **Name**: (Optional) The name field is optional, but if you enter a name it must be unique. + - **Description**: (Optional) An optional description of the Boundary storage policy for identification purposes. + - **Retention Policy**: (Required) Specifies how long a recording must be stored, in days. + Policy values include: + - `Forever`: If enabled, the **Deletion Policy** field is disabled. + - `Custom`: Specify a custom retention policy in days. + - `Do not protect, allow deletion at any time` + - `SOC 2 (7 years)` + - `HIPPA (6 years)` + - **Deletion Policy**: (Required) Specifies when to delete a recording, in days. + Policy values include: + - `Do not delete`: Do not delete recordings, even after the retention policy is met. + - `Custom`: Specifies the number of days after creation when a session recording should be deleted. + + As an example, the following settings would create a SOC 2 compliant policy: + + - **Name**: `soc2-policy` + - **Description**: `SOC 2 compliant storage policy for session recordings` + - **Retention Policy**: `SOC 2 (7 years)` + - **Deletion Policy**: `Custom` + Delete after: `2657` days + Toggle the switch beside **Allow orgs to override**. + +1. Click **Save**. + + + + +1. Log in to Boundary. +1. Use the following command to create a storage policy in Boundary: + + ```shell-session + $ boundary policies create storage \ + -name soc2-policy \ + -description 'SOC 2 compliant storage policy for session recordings' \ + -scope-id global \ + -retain-for-days 2557 \ + -retain-for-overridable false \ + -delete-after-days 2657 \ + -delete-after-overridable true + ``` + + The following [attributes](/boundary/docs/concepts/domain-model/storage-policies) can be used when defining a storage policy: + + - `name`: (Optional) An optional human readable name. + - `description`: (Optional) An optional human readable description. + - `scope-id`: (Optional) The ID of the scope (global or an org) that owns the policy. Defaults to `global`. + - `retain-for-days`: (Optional) The number of days a session recording must be kept. A value of `-1` indicates an infinite retention. + - `retain-for-overridable`: (Optional) Indicates that a lower scope can override the `retain_for_days` attribute value. Defaults to `true`. + - `delete-after-days`: (Optional) The number of days after creation when a session recording should be deleted. + - `delete-after-overridable`: (Optional) Indicates that a lower scope can override the `delete_after_days` attribute value. Defaults to `true`. + + + + +The following API call is an example of creating a storage policy in Boundary: + +```shell-session +$ curl --header "Content-Type: application/json" \ + --header "Authorization: Bearer $(boundary config get-token)" \ + --request POST \ + --data '{"attributes":{"retain_for":{"days":2557,"overridable":false},"delete_after":{"days":2657,"overridable":true}},"scope_id":"global","description":"SOC 2 compliant storage policy for session recordings","name":"soc2-policy","type":"storage"}' \ + $BOUNDARY_ADDR/v1/policies | jq +``` + + + + This example uses [jq](https://stedolan.github.io/jq/download/) to process the JSON output for readability. + + + +**Example output:** + + + +```plaintext +{ + "id": "pst_wV4bWSYYwL", + "scope_id": "global", + "scope": { + "id": "global", + "type": "global", + "name": "global", + "description": "Global Scope" + }, + "name": "soc2-api-test", + "description": "SOC 2 compliant storage policy for session recordings", + "created_time": "2024-01-26T03:44:58.119640Z", + "updated_time": "2024-01-26T03:44:58.119640Z", + "type": "storage", + "version": 1, + "attributes": { + "delete_after": { + "days": 2657, + "overridable": true + }, + "retain_for": { + "days": 2557, + "overridable": false + } + }, + "authorized_actions": [ + "no-op", + "read", + "update", + "delete" + ] +} +``` + + + + + + +In this example, recordings stored within the global scope must be retained for 7 years (2557 days), and will be automatically deleted 100 days later (at 2657 days). Scopes beneath `global` will not be able to override this retention policy, but are able to override the deletion policy. + + + + Boundary does not support an undo action. Storage policies are meant to enforce compliance to a specific law or regulation. Updating the storage policy of a session recording can have immediate and possibly unexpected results such as the immediate deletion of session recordings. + + + +## Attach storage policies to a scope + +You must apply storage policies to a scope (`global` or a specific org) to take effect. Once attached, all recordings within the child scopes inherit the storage policy, unless overridden by a policy applied to the child scope. + +The following example applies the policy created above to an org named `prod-databases` with the org ID `o_aDkVBCDTvY`. + + + + +1. Log in to Boundary. +1. Select **Orgs** in the navigation panel and select the `prod-databases` org. +1. Select **Org Settings** in the navigation panel for the `prod-databases` org. +1. Under **Storage Policy**, click **Add Storage Policy**. +1. Select the `soc2-policy`. +1. Click **Save**. This applies the policy to this scope and its children. + + + + +1. Log in to Boundary. +1. Obtain the storage policy ID: + + + + ```shell-session + $ boundary policies list + Policy information: + ID: pst_WZ3SQSSYJY + Version: 1 + Type: storage + Name: soc2-policy + Description: SOC 2 compliant storage policy for session recordings + Authorized Actions: + read + update + delete + no-op + ``` + + + +1. Use the following command to apply the storage policy to the `prod-databases` org: + + ```shell-session + $ boundary scopes attach-storage-policy \ + -id o_aDkVBCDTvY \ + -storage-policy-id pst_WZ3SQSSYJY + ``` + + + + +The following API call is an example of attaching a storage policy to a scope. + +First, obtain the storage policy ID. + +```shell-session +$ curl --header "Content-Type: application/json" \ + --header "Authorization: Bearer $(boundary config get-token)" \ + --request POST \ + $BOUNDARY_ADDR/v1/policies?scope_id=global' | jq +``` + +In this example, the storage policy ID is `pst_WZ3SQSSYJY`. + +Now attach the policy to the org. + +```shell-session +$ curl --header "Content-Type: application/json" \ + --header "Authorization: Bearer $(boundary config get-token)" \ + --request POST \ + --data '{"storage_policy_id":"pst_WZ3SQSSYJY","version":2}'' \ + $BOUNDARY_ADDR/v1/scopes/o_aDkVBCDTvY:attach-storage-policy' | jq +``` + +**Example output:** + + + +```plaintext +{ + "id": "o_aDkVBCDTvY", + "scope_id": "global", + "scope": { + "id": "global", + "type": "global", + "name": "global", + "description": "Global Scope" + }, + "name": "prod-databases", + "created_time": "2024-01-26T04:22:45.891800Z", + "updated_time": "2024-01-26T05:00:27.333892Z", + "version": 3, + "type": "org", + "authorized_actions": [ + "delete", + "attach-storage-policy", + "detach-storage-policy", + "no-op", + "read", + "update" + ], + "authorized_collection_actions": { + "auth-methods": [ + "create", + "list" + ], + "auth-tokens": [ + "list" + ], + "groups": [ + "create", + "list" + ], + "policies": [ + "list", + "create" + ], + "roles": [ + "list", + "create" + ], + "scopes": [ + "list", + "list-keys", + "rotate-keys", + "list-key-version-destruction-jobs", + "destroy-key-version", + "create" + ], + "session-recordings": [ + "list" + ], + "storage-buckets": [ + "list", + "create" + ], + "users": [ + "create", + "list" + ] + }, + "storage_policy_id": "pst_WZ3SQSSYJY" +} +``` + + + + + + +### Verify attached policies + +Check that the storage policy was successfully attached to the `prod-databases` scope. + + + + +1. Log in to Boundary. +1. Select **Orgs** in the navigation panel and select the `prod-databases` org. +1. Select **Org Settings** in the navigation panel for the `prod-databases` org. +1. Verify that the `soc2-policy` is listed under **Storage Policy**. + + + + +1. Log in to Boundary. +1. Read the details of the `prod-databases` org: + + + + ```shell-session + $ boundary scopes read -id o_aDkVBCDTvY + Scope information: + Created Time: Thu, 25 Jan 2024 21:22:45 MST + ID: o_aDkVBCDTvY + Name: prod-databases + Storage Policy ID: pst_WZ3SQSSYJY + Updated Time: Thu, 25 Jan 2024 22:00:27 MST + Version: 7 + + Scope (parent): + ID: global + Name: global + Type: global + + Authorized Actions: + detach-storage-policy + no-op + read + update + delete + attach-storage-policy + ... + ... More Output ... + ... + ``` + + + + Verify that the `soc2-policy` ID (`pst_WZ3SQSSYJY` in this example) is listed under **Storage Policy ID**. + + + + +The following API call is an example of reading the details of the `prod-databases` scope by ID (`o_aDkVBCDTvY` in this example). + +```shell-session +$ curl --header "Content-Type: application/json" \ + --header "Authorization: Bearer $(boundary config get-token)" \ + --request GET \ + $BOUNDARY_ADDR/v1/scopes/o_aDkVBCDTvY | jq +``` + +**Example output:** + + + +```plaintext +{ + "id": "o_aDkVBCDTvY", + "scope_id": "global", + "scope": { + "id": "global", + "type": "global", + "name": "global", + "description": "Global Scope" + }, + "name": "prod-databases", + "created_time": "2024-01-26T04:22:45.891800Z", + "updated_time": "2024-01-26T05:00:27.333892Z", + "version": 7, + "type": "org", + "authorized_actions": [ + "update", + "delete", + "attach-storage-policy", + "detach-storage-policy", + "no-op", + "read" + ], + "authorized_collection_actions": { + "auth-methods": [ + "create", + "list" + ], + "auth-tokens": [ + "list" + ], + "groups": [ + "create", + "list" + ], + "policies": [ + "list", + "create" + ], + "roles": [ + "list", + "create" + ], + "scopes": [ + "list", + "list-keys", + "rotate-keys", + "list-key-version-destruction-jobs", + "destroy-key-version", + "create" + ], + "session-recordings": [ + "list" + ], + "storage-buckets": [ + "create", + "list" + ], + "users": [ + "create", + "list" + ] + }, + "storage_policy_id": "pst_WZ3SQSSYJY" +} +``` + + + +Verify that the `soc2-policy` ID (`pst_WZ3SQSSYJY` in this example) is listed under `storage_policy_id`. + + + + +### Read and list session recordings + +New session recordings under the `prod-databases` scope should now show a `retain_until` and `delete_after` date corresponding to the `soc2-policy` storage policy. + + + + +1. Create a new session recording on a target within the `prod-databases` org. +1. Log in to Boundary. +1. Select **Session Recordings** in the navigation panel. +1. Select **View** for a new recording that was made after the storage policy was attached to the `prod-databases` scope. +1. Under **Session details**, verify that the *Retain until* and *Delete after* dates match the durations defined in the `soc2-policy`. + + + + +1. Create a new session recording on a target within the `prod-databases` org. +1. Log in to Boundary. +1. List the available session recordings: + + + + ```shell-session + $ boundary session-recordings list + + Session Recording information: + ID: sr_nt5dFeBYdh + Storage Bucket ID: sb_DC8SPb9uc2 + Created Time: Mon, 29 Jan 2024 23:25:31 MST + Updated Time: Tue, 30 Jan 2024 00:26:01 MST + Start Time: Mon, 29 Jan 2024 23:25:32 MST + End Time: Mon, 29 Jan 2024 23:25:53 MST + Type: ssh + State: available + Retain Until: Wed, 29 Jan 2031 23:25:53 MST + Delete After: Sat, 10 May 2031 00:25:53 MDT + Authorized Actions: + reapply-storage-policy + no-op + read + download + delete + ``` + + + + Copy the recording **ID** (such as `sr_nt5dFeBYdh`). + +1. Read the recording details by ID. + + + + ```shell-session + $ boundary session-recordings read -id sr_nt5dFeBYdh + + Session Recording information: + Bytes Down: 710 + Bytes Up: 36 + Created Time: Mon, 29 Jan 2024 23:25:31 MST + Delete After: Sat, 10 May 2031 00:25:53 MDT + Duration (Seconds): 21.01881 + Endpoint: ssh://xx.xxx.xxx.xxx:22 + ID: sr_nt5dFeBYdh + Retain Until: Wed, 29 Jan 2031 23:25:53 MST + Scope ID: global + Start Time: Mon, 29 Jan 2024 23:25:32 MST + State: available + Storage Bucket ID: sb_DC8SPb9uc2 + Type: ssh + Updated Time: Mon, 29 Jan 2024 23:25:53 MST + + ... + ... More Output ... + ... + ``` + + + + Verify that the `Retain Until` and `Delete After` dates match the durations defined in the 'soc2-policy'. + + + + +1. Create a new session recording on a target within the `prod-databases` org. +1. The following API call is an example of reading the details of a session recording with the `soc2-policy` storage policy applied to the `prod-databases` scope. + + List the available session recordings. This example recursively lists all recordings within the global scope. + + ```shell-session + $ curl --header "Content-Type: application/json" \ + --header "Authorization: Bearer $(boundary config get-token)" \ + --request GET \ + $BOUNDARY_ADDR/v1/session-recordings?recursive=true&scope_id=global | jq + ``` + + **Example output:** + + + + ```plaintext + { + "items": [ + { + "id": "sr_nt5dFeBYdh", + "scope": { + "id": "global", + "type": "global", + "name": "global", + "description": "Global Scope" + }, + "storage_bucket_id": "sb_DC8SPb9uc2", + "created_time": "2024-01-30T06:25:31.873628Z", + "updated_time": "2024-01-30T07:26:01.182513Z", + "start_time": "2024-01-30T06:25:32.412373Z", + "end_time": "2024-01-30T06:25:53.431183Z", + "duration": "21.018810s", + "type": "ssh", + "state": "available", + "endpoint": "ssh://xx.xxx.xxx.xxx:22", + "create_time_values": { + "user": { + "id": "u_lLWuYy70Wo", + "name": "admin_user", + "description": "Global admin user", + "scope": { + "id": "global", + "type": "global", + "name": "global", + "description": "Global Scope" + } + }, + "target": { + "id": "tssh_cjTsFSU10p", + "name": "recording-target", + "scope": { + "id": "p_ocJPxzrz2p", + "type": "project", + "name": "recording-project", + "parent_scope_id": "o_aDkVBCDTvY" + }, + "session_max_seconds": 28800, + "session_connection_limit": -1, + "egress_worker_filter": "\"recording-worker\" in \"/tags/type\"", + "type": "ssh", + "attributes": { + "default_port": 22 + } + } + }, + "authorized_actions": [ + "reapply-storage-policy", + "no-op", + "read", + "download", + "delete" + ], + "retain_until": "2031-01-30T06:25:53.431183Z", + "delete_after": "2031-05-10T06:25:53.431183Z" + } + ], + "response_type": "complete", + "list_token": "GnJNt3mPNy6Cp62MUBCnZPdrQF7cvh4udEoW4CjL5k2ufvesMfKAheSJyNHmKf3zwL5aVKHT4P6q", + "sort_by": "created_time", + "sort_dir": "desc", + "est_item_count": 1 + } + ``` + + + +1. Verify that the `retain_until` and `delete_after` dates match the durations defined in the `soc2-policy`. + +Alternatively, the recording details can also be queried directly by ID: + +```shell-session +$ curl --header "Content-Type: application/json" \ + --header "Authorization: Bearer $(boundary config get-token)" \ + --request GET \ + $BOUNDARY_ADDR/v1/session-recordings/sr_nt5dFeBYdh | jq +``` + + + + + + + Existing recordings within a scope or its children do not automatically have new or updated polices applied to them. Policies must be re-applied to existing recordings to take effect. Refer to the [Update storage bucket policies](/boundary/docs/configuration/session-recording/update-storage-policy) page for more details. + + + +### Manual deletion + +Deleting a session recording will set the `delete_after` field of a session recording to the current database time. Deleting a session recording will fail if the retention duration has not been met. + +If `delete_after` or `delete_time` is after the current time, the session recording will no longer be included in list responses; it also cannot be read, downloaded or played back. + +## Next steps + +After the storage policy is configured in Boundary, new recordings within the applied scope adhere to the defined policy. To retroactively apply the configured policy to existing recordings, refer to [update storage bucket policies](/boundary/docs/configuration/session-recording/update-storage-policy). + +[storage bucket]: /boundary/docs/concepts/domain-model/storage-buckets +[storage policy]: /boundary/docs/concepts/domain-model/storage-policy +[session recordings]: /boundary/docs/concepts/domain-model/session-recordings \ No newline at end of file diff --git a/website/content/docs/configuration/session-recording/create-storage-bucket.mdx b/website/content/docs/configuration/session-recording/create-storage-bucket.mdx index c04b501de..f43e32d70 100644 --- a/website/content/docs/configuration/session-recording/create-storage-bucket.mdx +++ b/website/content/docs/configuration/session-recording/create-storage-bucket.mdx @@ -14,10 +14,10 @@ A Boundary resource known as a [storage bucket](/boundary/docs/concepts/domain-m The storage bucket represents a bucket in an external store. Before you can enable session recording, you must create one or more storage buckets in Boundary and associate them with the external store. -A storage bucket can only belong to the Global scope or an Org scope. -A storage bucket that is associated with the Global scope can be associated with any target. -However, a storage bucket in an Org scope can only be associated with targets in a project from the same Org scope. -Any storage buckets associated with an Org scope are deleted when the Org itself is deleted. +A storage bucket can only belong to the global scope or an org scope. +A storage bucket that is associated with the global scope can be associated with any target. +However, a storage bucket in an Org scope can only be associated with targets in a project from the same org scope. +Any storage buckets associated with an Org scope are deleted when the org itself is deleted. For more information about using session recording to audit user sessions, refer to [Auditing](/boundary/docs/concepts/auditing). @@ -45,9 +45,12 @@ At this time, the only supported storage is AWS S3. "Action": [ "s3:PutObject", "s3:GetObject", - "s3:GetObjectAttributes" + "s3:GetObjectAttributes", + "s3:DeleteObject", + "s3:ListBucket" ], "Effect": "Allow", + "Resource": "arn:aws:s3:::session_recording_storage*", "Resource": "arn:aws:s3:::session_recording_storage/foo/bar/zoo/*" }, { @@ -86,7 +89,9 @@ At this time, the only supported storage is AWS S3. "Action": [ "s3:PutObject", "s3:GetObject", - "s3:GetObjectAttributes" + "s3:GetObjectAttributes", + "s3:DeleteObject", + "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::test-session-recording-bucket/*" diff --git a/website/content/docs/configuration/session-recording/update-storage-policy.mdx b/website/content/docs/configuration/session-recording/update-storage-policy.mdx new file mode 100644 index 000000000..38495d708 --- /dev/null +++ b/website/content/docs/configuration/session-recording/update-storage-policy.mdx @@ -0,0 +1,326 @@ +--- +layout: docs +page_title: Update storage bucket policies +description: |- + How to update a storage bucket policy for session recordings in Boundary +--- + +# Update storage bucket policies + +This feature requires HCP Boundary or Boundary Enterprise + +A [storage policy][] codifies [storage bucket][] lifecycle management for [session recordings][]. + +A storage policy exists in either the global scope or an org scope. Storage policies that are created in the global scope can be associated with any org scope. + +When you update a storage policy, new session recordings within a scope where the policy is applied will conform to the updated policy. Existing recordings will maintain the previous policy unless the new policy is retroactively applied. + +This page describes the process for applying updated storage policies to existing recordings within a scope. + +For more information about setting up storage bucket policies, refer to the [configure storage bucket policies](/boundary/docs/configuration/session-recording/configure-storage-policy) page. + +## Requirements + +This page continues the workflows outlined in the [configure storage bucket policies](/boundary/docs/configuration/session-recording/configure-storage-policy) page. The requirements outlined in that page are prerequisites for the workflow defined below. + +To apply an updated storage policy to existing session recordings, you first need: + +1. An external storage provider configured to store session recordings. +1. A Boundary worker configured for local storage. +1. A Boundary storage bucket with a defined retention and/or deletion policy. +1. A scope with the storage policy attached. +1. A set of session recordings made when the storage policy was attached. + +The policies mentioned here demonstrate how to apply an updated storage policy to an existing set of [session recordings][]. + +## Storage policy changes + +A storage policy defines how long the recording within a scope should retain its session recordings. + +Over time, you may update storage policies to reflect new organizational requirements, compliance changes, or cost management strategies. While updated policies automatically apply to new session recordings within the scopes associated with that policy, existing recordings maintain the previous policies unless you apply the new policy directly to those recordings. + +In the [configure storage bucket policies](/boundary/docs/configuration/session-recording/configure-storage-policy) page, the following policy was created to implement compliance with SOC-2 retention requirement of 7 years: + +- Name: `soc2-policy` +- Description: `SOC 2 compliant storage policy for session recordings` +- Retention policy: `2557` days, Overridable: `false` +- Deletion policy: `2657` days, Overridable: `true` + +## Update a storage policy + +In the following example, the `soc2-policy` should be updated to the following: + +- Name: `soc2-policy` +- Description: `SOC 2 compliant storage policy for session recordings, V2` +- Retention policy: `2557` days, Overridable: `false` +- Deletion policy: `2757` days, Overridable: `false` + +The updated policy requires the deletion of recordings after `2757` days, 200 days after the standard SOC 2 retention requirements. It also changes Overridable to `false`, preventing lower scopes from overwriting the Deletion policy. + +The following is an example of updating the `soc2-policy` policy. + + + + +1. Log in to Boundary. +1. Select **Storage Policies** in the navigation panel and select the `global` scope. +1. Click on **`soc2-policy`**. +1. Click the **Edit Form** button and update the following fields: + - **Description**: `SOC 2 compliant storage policy for session recordings, V2` + - **Retention Policy**: `SOC 2 (7 years)` + - **Deletion Policy**: `Custom` + **Delete after**: `2757` days + Toggle the switch beside **Allow orgs to override** to the off position. + +1. Click **Save**. + + + + +1. Log in to Boundary. +1. List the available storage policies and copy the `soc2-policy` ID. + + + + ```shell-session + $ boundary policies list + Policy information: + ID: pst_WZ3SQSSYJY + Version: 1 + Type: storage + Name: soc2-policy + Description: SOC 2 compliant storage policy for session recordings + Authorized Actions: + read + update + delete + no-op + ``` + + + +1. Use the following command to update the `soc2-policy` storage policy to reflect the new deletion requirements: + + ```shell-session + $ boundary policies update storage \ + -id pst_WZ3SQSSYJY \ + -description 'SOC 2 compliant storage policy for session recordings, V2' \ + -scope-id global \ + -retain-for-days 2557 \ + -retain-for-overridable false \ + -delete-after-days 2757 \ + -delete-after-overridable false + ``` + + + + +The following API call is an example of updating a storage policy in Boundary: + +```shell-session +$ curl --header "Content-Type: application/json" \ + --header "Authorization: Bearer $(boundary config get-token)" \ + --request PATCH \ + --data '{"attributes":{"retain_for":{"days":2557,"overridable":false},"delete_after":{"days":2757,"overridable":false}},"scope_id":"global","description":"SOC 2 compliant storage policy for session recordings, V2","type":"storage","version":"2"}' \ + $BOUNDARY_ADDR/v1/policies/pst_WZ3SQSSYJY | jq +``` + + + + This example uses [jq](https://stedolan.github.io/jq/download/) to process the JSON output for readability. + + + +**Example output:** + + + +```plaintext +{ + "id": "pst_WZ3SQSSYJY", + "scope_id": "global", + "scope": { + "id": "global", + "type": "global", + "name": "global", + "description": "Global Scope" + }, + "name": "soc2-policy", + "description": "SOC 2 compliant storage policy for session recordings, V2", + "created_time": "2024-01-25T22:05:52.112677Z", + "updated_time": "2024-01-30T22:44:08.890715Z", + "type": "storage", + "version": 2, + "attributes": { + "delete_after": { + "days": 2757, + "overridable": false + }, + "retain_for": { + "days": 2557, + "overridable": false + } + }, + "authorized_actions": [ + "no-op", + "read", + "update", + "delete" + ] +} +``` + + + + + + +This policy was applied to the `prod-databases` org in the [configure storage bucket policies](/boundary/docs/configuration/session-recording/configure-storage-policy) page. + +New recordings within the `prod-databases` org will automatically have the updated version of the `soc2-policy` applied. + +### Reapply a storage policy + +Many organizations compliance standards will require that previous versions of storage policies remain applied to existing recordings. + + + + During the initial migration to a Boundary version that includes storage policies, all existing session recordings will have a `retain_for` attribute of `-1`, which retains the recording forever. + + + +In the event that an updated policy should be retroactively applied to existing session recordings, you must reapply the storage policy. + + + + +1. Log in to Boundary. +1. Select **Session Recordings** in the navigation panel in the `global` scope. +1. Click on **View** for a session recording that should have the storage policy re-applied. +1. Click the **Manage** dropdown and select **Re-apply storage policy**. +1. Verify the *Delete after* field has been updated under the recording's **Session details**. + + + + +1. Log in to Boundary. +1. Find the ID of the session recording that should have the storage policy re-applied. + + + + ```shell-session + $ boundary session-recordings list + Session Recording information: + ID: sr_nt5dFeBYdh + Storage Bucket ID: sb_DC8SPb9uc2 + Created Time: Mon, 29 Jan 2024 23:25:31 MST + Updated Time: Tue, 30 Jan 2024 16:14:13 MST + Start Time: Mon, 29 Jan 2024 23:25:32 MST + End Time: Mon, 29 Jan 2024 23:25:53 MST + Type: ssh + State: available + Retain Until: Wed, 29 Jan 2031 23:25:53 MST + Delete After: Mon, 18 Aug 2031 00:25:53 MDT + Authorized Actions: + no-op + read + download + delete + reapply-storage-policy + ``` + + + +1. Re-apply the storage policy to the session recording by providing its ID: + + + + ```shell-session + $ boundary session-recordings reapply-storage-policy -id sr_nt5dFeBYdh + Session Recording information: + Bytes Down: 710 + Bytes Up: 36 + Created Time: Mon, 29 Jan 2024 23:25:31 MST + Delete After: Mon, 18 Aug 2031 00:25:53 MDT + Duration (Seconds): 21.01881 + Endpoint: ssh://54.159.144.135:22 + ID: sr_nt5dFeBYdh + Retain Until: Wed, 29 Jan 2031 23:25:53 MST + Scope ID: global + Start Time: Mon, 29 Jan 2024 23:25:32 MST + State: available + Storage Bucket ID: sb_DC8SPb9uc2 + Type: ssh + Updated Time: Mon, 29 Jan 2024 23:25:53 MST + + ... + ... More Output ... + ... + ``` + + + + Verify that the `Delete After` attribute reflects the updated storage policy. + + + + +The following API call is an example of re-applying a storage policy to a session recording by providing the recording's ID: + +```shell-session +$ curl --header "Content-Type: application/json" \ + --header "Authorization: Bearer $(boundary config get-token)" \ + --request POST \ + $BOUNDARY_ADDR/v1/session-recordings/sr_nt5dFeBYdh:reapply-storage-policy | jq +``` + +**Example output:** + + + +```plaintext +{ + "id": "sr_nt5dFeBYdh", + "scope": { + "id": "global", + "type": "global", + "name": "global", + "description": "Global Scope" + }, + "storage_bucket_id": "sb_DC8SPb9uc2", + "bytes_up": "36", + "bytes_down": "710", + "created_time": "2024-01-30T06:25:31.873628Z", + "updated_time": "2024-01-30T23:14:13.881110Z", + "start_time": "2024-01-30T06:25:32.412373Z", + "end_time": "2024-01-30T06:25:53.431183Z", + "duration": "21.018810s", + "type": "ssh", + "state": "available", + "endpoint": "ssh://xx.xxx.xxx.xxx:22", + +... +... More Output ... +... + + "retain_until": "2031-01-30T06:25:53.431183Z", + "delete_after": "2031-08-18T06:25:53.431183Z" +} +``` + + + +Verify that the `delete_after` attribute reflects the updated storage policy. + + + + +### Detached or deleted storage policies + +If a scope's storage policy is detached or deleted, new session recordings within that scope will automatically be retained forever, unless there is an overriding policy. + +Existing session recordings will maintain their existing storage policy attributes until a new policy is re-applied, including any overriding policy from another scope. + +[storage bucket]: /boundary/docs/concepts/domain-model/storage-buckets +[storage policy]: /boundary/docs/concepts/domain-model/storage-policy +[session recordings]: /boundary/docs/concepts/domain-model/session-recordings \ No newline at end of file diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 4a3dfbde2..2245f75b8 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -310,6 +310,15 @@ }, "path": "concepts/domain-model/storage-buckets" }, + { + "title": "Storage policies", + "badge": { + "text": "HCP/ENT", + "type": "outlined", + "color": "neutral" + }, + "path": "concepts/domain-model/storage-policy" + }, { "title": "Targets", "path": "concepts/domain-model/targets" @@ -448,6 +457,14 @@ { "title": "Enable session recording", "path": "configuration/session-recording/enable-session-recording" + }, + { + "title": "Configure storage policies", + "path": "configuration/session-recording/configure-storage-policy" + }, + { + "title": "Update storage policies", + "path": "configuration/session-recording/update-storage-policy" } ] }, @@ -1056,6 +1073,40 @@ } ] }, + { + "title": "policies", + "badge": { + "text": "HCP/ENT", + "type": "outlined", + "color": "neutral" + }, + "routes": [ + { + "title": "Overview", + "path": "commands/policies" + }, + { + "title": "create", + "path": "commands/policies/create" + }, + { + "title": "delete", + "path": "commands/policies/delete" + }, + { + "title": "list", + "path": "commands/policies/list" + }, + { + "title": "read", + "path": "commands/policies/read" + }, + { + "title": "update", + "path": "commands/policies/update" + } + ] + }, { "title": "roles", "routes": [