gravitational / teleport

The easiest, and most secure way to access and protect all of your infrastructure.
https://goteleport.com
GNU Affero General Public License v3.0
17.36k stars 1.74k forks source link

Limit the scope of require_session_join to only the role it is part of #16794

Open WilliamLoy opened 1 year ago

WilliamLoy commented 1 year ago

Expected behavior: A role with require_session_join should not apply to resource labels in a separate role without require_session_join when both roles are assigned to the same user.

Customers need the ability to create tiers of access severity across commonly used architectures, such as an environment with a Testing, Staging, and Production environment.

Current behavior: If a user is assigned a role without require_session_join and a role with require_session_join, the session joining requirement is applied to all other roles assigned to that user.

This behavior prevents a customer from being able to specify permissive access for development environments and restrictive access for production environments for the same user. This is very disruptive to a user who works in multiple levels of access severity. Customers should not be required to make their lower environments just as restrictive as their production environments.

For example:

kind: role
metadata:
  id: 1664308724133715309
  name: operator
spec:
  allow:
    join_sessions:
    - kinds:
      - ssh
      modes:
      - peer
      - observer
      name: Ops oversight
      roles:
      - session-join
    logins:
    - root
    - ubuntu
    node_labels:
      aws/Environment: DEV
  deny: {}
  options:
    cert_format: standard
    create_host_user: false
    desktop_clipboard: true
    desktop_directory_sharing: true
    enhanced_recording:
    - command
    - network
    forward_agent: false
    max_session_ttl: 8h0m0s
    pin_source_ip: false
    port_forwarding: true
    record_session:
      default: best_effort
      desktop: true
    ssh_file_copy: true
version: v5

The operator role above doesn't require session joining to access resources labeled with aws/Environment: DEV. This works as expected. If we add the following session-join role to the same user, aws/Environment: DEV is forced to require a joined session even though that is not a requirement of the operator role.

kind: role
metadata:
  id: 1664308814819653431
  name: session-join
spec:
  allow:
    logins:
    - root
    - ubuntu
    node_labels:
      aws/Environment: prod
    require_session_join:
    - count: 1
      filter: contains(user.roles, "operator")
      kinds:
      - ssh
      modes:
      - peer
      - observer
      name: Auditor oversight
      on_leave: ""
  deny: {}
  options:
    cert_format: standard
    create_host_user: false
    desktop_clipboard: true
    desktop_directory_sharing: true
    enhanced_recording:
    - command
    - network
    forward_agent: false
    max_session_ttl: 30h0m0s
    pin_source_ip: false
    port_forwarding: true
    record_session:
      default: best_effort
      desktop: true
    ssh_file_copy: true
version: v5

The workaround would be to use an access request for the role with require_session_join. However, this presents a couple of problems:

  1. Additional RBAC work
  2. An additional step for the approver and requestor for a resource the requestor should already have access to without approval
  3. The requestor will be unable to join environments that would normally not require a joined session(without someone joining the session) for the duration of the time they assume the access request role.

Bug details:

dmsergeevN26 commented 1 year ago

This is exactly the issue we've been facing recently. It is indeed counter intuitive that require_session_join are scoped like that and it's a giant pain having to work around it.

My suggestion would be to scope it to <node, os login> and not just node as to enable the following workflow: regular infrastructure access requires moderation but incident resolution activities do not.

Another idea would be to move evaluation of require_session_join filters and counts on session start and not join. this would allow me to specify a policy that would have count set to 1 and if the user has the oncall role then the filter is satisfied

klizhentas commented 1 year ago

@nklaassen The idea is to limit require session join only to resources that match the labels in this role. Backwards compatibility, create a v7

allow:
 require_session_join:
  ...
kube_labels:
   * : * 
dmsergeevN26 commented 1 year ago

Is it possible to limit it to <node, os login> tuple for servers? this could greatly help us where a user would then be able to pick whether or not to use an unmoderated oncall login or the regular moderated one

codingllama commented 1 year ago

We could solve this, without breakages, by letting customers specify different "require_session_join" modes:

ravicious commented 1 month ago

FWIW, the same "poison pill" problem exists with ssh_file_copy (https://github.com/gravitational/teleport/issues/38567, https://github.com/gravitational/teleport/issues/20116) and would likely require a similar solution.