From e8ed183adbb70d2b8856a7c4004a26e277208c92 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 11 Feb 2022 20:07:46 +0100 Subject: [PATCH] Add documentation for moderated sessions (#9425) (#10302) --- docs/config.json | 3 +- .../pages/access-controls/getting-started.mdx | 2 +- docs/pages/access-controls/guides.mdx | 3 + .../access-controls/guides/dual-authz.mdx | 8 +- .../access-controls/guides/impersonation.mdx | 10 +- docs/pages/access-controls/guides/locking.mdx | 4 +- .../guides/moderated-sessions.mdx | 182 ++++++++++++++++++ .../guides/per-session-mfa.mdx | 4 +- .../access-controls/guides/role-templates.mdx | 12 +- docs/pages/access-controls/reference.mdx | 43 ++++- docs/pages/api/architecture.mdx | 2 +- docs/pages/application-access/controls.mdx | 2 +- .../application-access/guides/aws-console.mdx | 2 +- .../guides/mysql-self-hosted.mdx | 2 +- .../guides/postgres-self-hosted.mdx | 2 +- docs/pages/database-access/rbac.mdx | 4 +- docs/pages/desktop-access/getting-started.mdx | 2 +- docs/pages/desktop-access/reference.mdx | 2 +- docs/pages/enterprise/sso.mdx | 4 +- docs/pages/enterprise/sso/azuread.mdx | 2 +- docs/pages/enterprise/sso/gitlab.mdx | 4 +- docs/pages/enterprise/sso/okta.mdx | 2 +- docs/pages/enterprise/sso/one-login.mdx | 2 +- docs/pages/enterprise/workflow/index.mdx | 8 +- .../workflow/ssh-approval-jira-cloud.mdx | 2 +- .../workflow/ssh-approval-jira-server.mdx | 2 +- .../workflow/ssh-approval-mattermost.mdx | 2 +- .../workflow/ssh-approval-pagerduty.mdx | 2 +- .../workflow/ssh-approval-slack.mdx | 4 +- docs/pages/getting-started/docker-compose.mdx | 4 +- docs/pages/kubernetes-access/controls.mdx | 4 +- .../getting-started/cluster.mdx | 2 +- docs/pages/kubernetes-access/guides/cicd.mdx | 2 +- .../kubernetes-access/guides/migration.mdx | 2 +- .../guides/restricted-session.mdx | 2 +- docs/pages/setup/admin/trustedclusters.mdx | 2 +- docs/pages/setup/guides/ec2-tags.mdx | 2 +- docs/pages/setup/guides/fluentd.mdx | 4 +- .../pages/setup/guides/terraform-provider.mdx | 4 +- docs/pages/setup/reference/resources.mdx | 2 +- .../setup/security/reduce-blast-radius.mdx | 12 +- 41 files changed, 290 insertions(+), 75 deletions(-) create mode 100644 docs/pages/access-controls/guides/moderated-sessions.mdx diff --git a/docs/config.json b/docs/config.json index fda8278cf4145..4d2dccb1f69c2 100644 --- a/docs/config.json +++ b/docs/config.json @@ -238,7 +238,8 @@ { "title": "Second Factor - WebAuthn", "slug": "/access-controls/guides/webauthn/" }, { "title": "Per-session MFA", "slug": "/access-controls/guides/per-session-mfa/" }, { "title": "Dual Authorization", "slug": "/access-controls/guides/dual-authz/" }, - { "title": "Impersonation", "slug": "/access-controls/guides/impersonation/" } + { "title": "Impersonation", "slug": "/access-controls/guides/impersonation/" }, + { "title": "Moderated Sessions", "slug": "/access-controls/guides/moderated-sessions/" } ] }, { "title": "Reference", "slug": "/access-controls/reference/" }, diff --git a/docs/pages/access-controls/getting-started.mdx b/docs/pages/access-controls/getting-started.mdx index 169df79e66d99..41c19b7bc496a 100644 --- a/docs/pages/access-controls/getting-started.mdx +++ b/docs/pages/access-controls/getting-started.mdx @@ -122,7 +122,7 @@ Save this role as `interns.yaml`: ```yaml kind: role -version: v4 +version: v5 metadata: name: interns spec: diff --git a/docs/pages/access-controls/guides.mdx b/docs/pages/access-controls/guides.mdx index a2997aad1db59..caef5adda9d9f 100644 --- a/docs/pages/access-controls/guides.mdx +++ b/docs/pages/access-controls/guides.mdx @@ -23,4 +23,7 @@ layout: tocless-doc
  • [Locking](./guides/locking.mdx). Lock access to active user sessions or hosts.
  • +
  • + [Moderated Sessions](./guides/moderated-sessions.mdx). Require session auditors and allow fine-grained live session access. +
  • diff --git a/docs/pages/access-controls/guides/dual-authz.mdx b/docs/pages/access-controls/guides/dual-authz.mdx index 39a1a78f364bc..cdf8cb008d300 100644 --- a/docs/pages/access-controls/guides/dual-authz.mdx +++ b/docs/pages/access-controls/guides/dual-authz.mdx @@ -80,7 +80,7 @@ spec: version: v2 --- kind: role -version: v4 +version: v5 metadata: name: access-plugin spec: @@ -162,7 +162,7 @@ Create `dbadmin`, `reviewer` and `devops` roles: ```yaml kind: role -version: v4 +version: v5 metadata: name: reviewer spec: @@ -171,7 +171,7 @@ spec: roles: ['dbadmin'] --- kind: role -version: v4 +version: v5 metadata: name: devops spec: @@ -183,7 +183,7 @@ spec: deny: 1 --- kind: role -version: v4 +version: v5 metadata: name: dbadmin spec: diff --git a/docs/pages/access-controls/guides/impersonation.mdx b/docs/pages/access-controls/guides/impersonation.mdx index 6fdacfb46e372..38c4117fc9703 100644 --- a/docs/pages/access-controls/guides/impersonation.mdx +++ b/docs/pages/access-controls/guides/impersonation.mdx @@ -32,7 +32,7 @@ Save this file as `jenkins.yaml` to create the user and role: ```yaml kind: role -version: v4 +version: v5 metadata: name: jenkins spec: @@ -77,7 +77,7 @@ Save this role definition as `impersonator.yaml`: ```yaml kind: role -version: v4 +version: v5 metadata: name: impersonator spec: @@ -179,7 +179,7 @@ allowed the impersonation of any users or roles with the label ```yaml kind: role -version: v4 +version: v5 metadata: name: security-impersonator spec: @@ -214,7 +214,7 @@ Create a user and a role `security-scanner` using the following template: ```yaml kind: role -version: v4 +version: v5 metadata: name: security-scanner labels: @@ -256,7 +256,7 @@ as the label on the role and/or user to impersonate: ```yaml kind: role -version: v4 +version: v5 metadata: name: security-impersonator spec: diff --git a/docs/pages/access-controls/guides/locking.mdx b/docs/pages/access-controls/guides/locking.mdx index 2d12b8dbe2bba..cf998c047d872 100644 --- a/docs/pages/access-controls/guides/locking.mdx +++ b/docs/pages/access-controls/guides/locking.mdx @@ -105,7 +105,7 @@ Create a role `locksmith`: ```yaml kind: role -version: v4 +version: v5 metadata: name: locksmith spec: @@ -231,7 +231,7 @@ It is also possible to configure the locking mode for a particular role: ```yaml kind: role -version: v4 +version: v5 metadata: name: example-role-with-strict-locking spec: diff --git a/docs/pages/access-controls/guides/moderated-sessions.mdx b/docs/pages/access-controls/guides/moderated-sessions.mdx new file mode 100644 index 0000000000000..fee04919ef893 --- /dev/null +++ b/docs/pages/access-controls/guides/moderated-sessions.mdx @@ -0,0 +1,182 @@ +--- +title: Moderated Sessions +description: Moderated Sessions +h1: Moderated Sessions +--- + +## Introduction + +Moderated Sessions allows Teleport administrators to +define requirements for other users to be present in a Server or Kubernetes Access session. Depending on the requirements, these users can observe the session in real time, participate in the session, and terminate the session at will. + +### Use cases + +Moderated Sessions are useful in the following scenarios: +- When you have stringent security requirements and need to have people watching over user-initiated sessions on a set of servers. +- When you want to share a terminal with someone else to be able to instruct or collaborate. + +## Policies + +Moderated Sessions makes use of RBAC policies to allow for fine grained control over +who can join a session and who is required to be present to start one. + +The system is based around **require policies** and **allow policies**. + +Require policies define a set of conditions that must be a met for a session to start or run. +A minimum of one policy from each relevant role the user has must match for the session to start. + +Allow policies are used to define what sessions a user can join +and under what conditions they may join a session. + +## Configuring Moderated Sessions + +### `require_session_join` + +#### Options + +The following are required options for `require_session_join`: + +|Option|Type|Description| +|---|---|---| +|`name`|String|The name of the require policy| +|`filter`|[Filter](#filters)|An expression that, if it evaluates to true for a given user, enables the user to be present in a Moderated Session| +|`kinds`|`[]`[Session kind](#session-kinds)|The kind of session that the policy applies to| +|`modes`|`[]`[Participant mode](#participant-modes)|The participant mode that applies to the user joining the Moderated Session under this policy| +|`count`|Integer|The number of users that need to match the filter expression to satisfy the policy| + +#### Example + +The policy below specifies that the `prod-access` role +must have a minimum of two users with the role `auditor` and the mode `moderator` present in the session +to start it. The policy applies to SSH and Kubernetes sessions only. + +When a user with this require policy starts a session, it will be pending +until the policy is fulfilled. + +```yaml +kind: role +metadata: + name: prod-access +spec: + allow: + require_session_join: + - name: Auditor oversight + filter: 'contains(user.roles, "auditor")' + kinds: ['k8s', 'ssh'] + modes: ['moderator'] + count: 2 +``` + +### `join_sessions` + +#### Options + +The following are required options for `join_sessions`: + +|Option|Type|Description| +|---|---|---| +|`name`|String|The name of the allow policy| +|`roles`|[]String|A list of names for Teleport roles that this policy applies to. Users with this role are eligible to join a Moderated Session under this policy.| +|`kinds`|`[]`[Session kind](#session-kinds)|The kind of session that the policy applies to| +|`modes`|`[]`[Participant mode](#participant-modes)|The participant mode that applies to the user joining the Moderated Session under this policy| + +#### Example + +The following allow policy attaches to the role `auditor` and allows one to join +SSH and Kubernetes sessions started by a user with the role `prod-access` as a moderator or observer. + +```yaml +kind: role +metadata: + name: auditor +spec: + allow: + join_sessions: + - name: Auditor oversight + roles : ['prod-access'] + kinds: ['k8s', 'ssh'] + modes: ['moderator', 'observer'] +``` + +### Filters + +Filter expressions allow for more detailed control over the scope of an allow policy or require policy. + +Require policies can specify which users they consider as valid with a filter expression. +The filter context has a `user` object defined with the set fields `roles` and `name`. + +Here is an example of a filter expression that evaluates to true if the user is Adam or if the user has the trait `cs-observe`: + +``` +equals(user.name, "adam") || contains(user.roles, "cs-observe") +``` + +A filter expression is a string statement used to define logic based on a set of input variables. +The filter expressions follow a restricted subset of Go syntax and supports +the following functions and operators: +- `contains(set, item)`: Returns true if the item is in the set, otherwise false. The set can be a string or an array. +- `equals(a, b)`: Returns true if the two values are equal, otherwise returns false. +- `![expr]`: Negates a boolean expression. +- `[expr] && [expr]`: Performs a logical AND on two boolean expressions. +- `[expr] || [expr]`: Performs a logical OR on two boolean expressions. + +### Session kinds + +Require and allow policies have to specify which sessions they apply to. Valid options are `ssh` and `k8s`. + +- `ssh` policies apply to all SSH sessions on a node running the Teleport SSH server. +- `k8s` policies apply to all Kubernetes sessions on clusters connected to Teleport. + +### Participant modes +A participant joining a session will always have one of three modes: + +- `peer`: Can join and collaborate in a session. They can view output and send input. +- `moderator`: Can join and watch a session. They can view output and forcefully terminate the session at will. +- `observer`: Can join and watch a session. They cannot control the session in any way. + +When joining a session with `tsh join` or `tsh kube join`, a user can specify a mode with the `--mode ` flag +, where the mode is one of `peer`, `moderator` or `observer`. By default, the mode is `peer` for SSH and +`moderator` for Kubernetes sessions. + +A participant may leave a session with the shortcut `c` while in observer or moderator mode. +When in moderator mode, a participant may also forcefully terminate the session at any point in time +with the shortcut `t`. + +### Require policy count + +Require policies can have a variable amount of users that need to match the filter expression +in order to satisfy the policy. The `count` field of a require policy is a positive integer +value that specifies the minimum amount of users this policy requires. + +## Backwards compatibility with Server Access + +Previously, Server Access did not include controls over which users can join a session. +To work around this, RBAC rules are ignored for users that only have V4 roles (`version: v4` in the role specification). +New roles are created as V5. V4 roles are upgraded when they are modified in the UI. +If a user has any attached V5 roles (`version: v5` in the role specification), the new RBAC access checks will be enforced. + +## MFA-based presence + +When `per_session_mfa` is set to `true` via [role or cluster settings](../../access-controls/guides/per-session-mfa.mdx), Teleport enforces +MFA-based presence checks for moderators. +This requires that all moderators wishing to join have a configured U2F or WebAuthn MFA token. + +Every 30 seconds, Teleport will issue a prompt to the user in the terminal, asking them +to press their MFA token in the next 15 seconds. This will happen continously during the session +and exists so that moderators are always present and watching a given session. + +If no MFA input is received within 60 seconds, the user is kicked +from the session which may pause it, if RBAC policies are no longer met. + +## Session invites + +When starting an interactive SSH or Kubernetes session using `tsh ssh` or `tsh kube exec` respectively, +one may supply a `--reason ` and/or an `--invited ` flag where `` +is a string and `` is a comma-separated list of usernames. + +This information can be picked up by a third party integration and may for example be used to +enable notifications over some external communication system. + +## RFD + +- [Moderated Sessions](https://github.com/gravitational/teleport/blob/master/rfd/0043-kubeaccess-multiparty.md) diff --git a/docs/pages/access-controls/guides/per-session-mfa.mdx b/docs/pages/access-controls/guides/per-session-mfa.mdx index e8be4d5063547..ba345130986ed 100644 --- a/docs/pages/access-controls/guides/per-session-mfa.mdx +++ b/docs/pages/access-controls/guides/per-session-mfa.mdx @@ -87,7 +87,7 @@ Olga defines two Teleport roles: `access-dev` and `access-prod`: ```yaml # access-dev.yaml kind: role -version: v4 +version: v5 metadata: name: access-dev spec: @@ -100,7 +100,7 @@ spec: --- # access-prod.yaml kind: role -version: v4 +version: v5 metadata: name: access-prod spec: diff --git a/docs/pages/access-controls/guides/role-templates.mdx b/docs/pages/access-controls/guides/role-templates.mdx index 90c63b98b9492..855808ef949e6 100644 --- a/docs/pages/access-controls/guides/role-templates.mdx +++ b/docs/pages/access-controls/guides/role-templates.mdx @@ -36,7 +36,7 @@ We can create two roles, one for each user in file `roles.yaml`: ```yaml kind: role -version: v4 +version: v5 metadata: name: alice spec: @@ -49,7 +49,7 @@ spec: '*': '*' --- kind: role -version: v4 +version: v5 metadata: name: bob spec: @@ -78,7 +78,7 @@ Let's create a role template `devs.yaml`: ```yaml kind: role -version: v4 +version: v5 metadata: name: devs spec: @@ -173,7 +173,7 @@ to be set by identity provider. Save this role as `sso-users.yaml`: ```yaml kind: role -version: v4 +version: v5 metadata: name: sso-users spec: @@ -255,7 +255,7 @@ Let's see how these variables are used with role template `interpolation`: ```yaml kind: role -version: v4 +version: v5 metadata: name: interpolation spec: @@ -288,7 +288,7 @@ behave as the following role: ```yaml kind: role -version: v4 +version: v5 metadata: name: interpolation spec: diff --git a/docs/pages/access-controls/reference.mdx b/docs/pages/access-controls/reference.mdx index c03db6d0e501b..3411ea7370aba 100644 --- a/docs/pages/access-controls/reference.mdx +++ b/docs/pages/access-controls/reference.mdx @@ -43,7 +43,7 @@ A role definition looks like this: ```yaml kind: role -version: v4 +version: v5 metadata: name: example spec: @@ -130,6 +130,35 @@ spec: - resources: [token] verbs: [list,create,read,update,delete] + # Moderated Sessions policy that dictates requirements for starting a session. + require_session_join: + # Defines the name of the policy. The name serves only as an + # identifier in logs and for organisation/categorisation. + - name: Auditor oversight + # Specifies an RBAC predicate that is used to define + # which users count against the required user count of the policy. + filter: 'contains(user.roles, "auditor")' + # The different session kinds this policy applies to. + kinds: ['k8s', 'ssh'] + # A list of session participant modes that a participant must have + # one of in order to count against the policy. + modes: ['moderator'] + # The minimum amount of users that need to match the filter expression + # in order to satisfy the policy. + count: 1 + + # Moderated Sessions policy that dictates the ability to join sessions + join_sessions: + # Defines the name of the policy. The name serves only as an + # identifier in logs and for organisation/categorisation. + - name: Auditor oversight + # Allows one to join sessions created by other users with these roles + roles : ['prod-access'] + # The different session kinds this policy applies to. + kinds: ['k8s', 'ssh'] + # The list of session participant modes the role may join the session as. + modes: ['moderator', 'observer'] + # The deny section uses the identical format as the 'allow' section. # The deny rules always override allow rules. deny: {} @@ -201,12 +230,12 @@ that are more appropriately scoped. ### Role versions -There are currently two supported role versions: `v3` and `v4`. `v4` roles are +There are currently two supported role versions: `v3` and `v5`. `v5` roles are completely backwards-compatible with `v3`, the only difference lies in the default allow labels which will be applied to the role if they are not explicitly set. -Label | `v3` Default | `v4` Default +Label | `v3` Default | `v5` Default ------------------ | -------------- | --------------- `node_labels` | `[{"*": "*"}]` if the role has any logins, else `[]` | `[]` `app_labels` | `[{"*": "*"}]` | `[]` @@ -234,7 +263,7 @@ Access to any other nodes will be denied: ```yaml kind: role -version: v4 +version: v5 metadata: name: example-role spec: @@ -264,7 +293,7 @@ Below are a few examples for more complex filtering using various regexes. ```yaml kind: role -version: v4 +version: v5 metadata: name: example-role spec: @@ -341,7 +370,7 @@ downgrade they will become invalid. Role for restricted access to session recordings: ```yaml -version: v4 +version: v5 kind: role metadata: name: only-own-sessions @@ -358,7 +387,7 @@ spec: Role for restricted access to active sessions: ```yaml -version: v4 +version: v5 kind: role metadata: name: only-own-ssh-sessions diff --git a/docs/pages/api/architecture.mdx b/docs/pages/api/architecture.mdx index 11a3bb3306d95..2363531aac0d1 100644 --- a/docs/pages/api/architecture.mdx +++ b/docs/pages/api/architecture.mdx @@ -36,7 +36,7 @@ spec: deny: node_labels: '*': '*' -version: v4 +version: v5 EOF # Create role tctl create -f api-role.yaml diff --git a/docs/pages/application-access/controls.mdx b/docs/pages/application-access/controls.mdx index c4956e432ddcf..b94f9ab26ff2c 100644 --- a/docs/pages/application-access/controls.mdx +++ b/docs/pages/application-access/controls.mdx @@ -41,7 +41,7 @@ For example, this role will grant access to all applications from the group ```yaml kind: role -version: v4 +version: v5 metadata: name: dev spec: diff --git a/docs/pages/application-access/guides/aws-console.mdx b/docs/pages/application-access/guides/aws-console.mdx index 0f991c29dd6f9..f6efd76959ecf 100644 --- a/docs/pages/application-access/guides/aws-console.mdx +++ b/docs/pages/application-access/guides/aws-console.mdx @@ -142,7 +142,7 @@ role ARNs this particular role permits its users to assume: ```yaml kind: role -version: v4 +version: v5 metadata: name: aws-console-access spec: diff --git a/docs/pages/database-access/guides/mysql-self-hosted.mdx b/docs/pages/database-access/guides/mysql-self-hosted.mdx index 046ea01b2580e..9646c7bab41e5 100644 --- a/docs/pages/database-access/guides/mysql-self-hosted.mdx +++ b/docs/pages/database-access/guides/mysql-self-hosted.mdx @@ -74,7 +74,7 @@ database account: ```bash tctl --config=/path/to/teleport-db-role.yaml create <