# Session and Identity Locking

System administrators can disable a compromised user or Teleport Agent—or prevent access during cluster maintenance—by placing a lock on a session, user or host identity.

Teleport will reject new API requests and terminate active connections to SSH, application, database, desktop, and Kubernetes sessions matching the lock's target.

A lock can target the following objects or attributes:

- a Teleport user by the user's name
- a Teleport [RBAC](https://goteleport.com/docs/reference/access-controls/roles.md) role by the role's name
- a Teleport [trusted device](https://goteleport.com/docs/zero-trust-access/device-trust/enforcing-device-trust.md#locking-a-device) by the device ID
- an MFA device by the device's UUID
- an OS/UNIX login
- a Teleport Agent by the Agent's server UUID (effectively unregistering it from the cluster)
- a Windows desktop by the desktop's name
- an [Access Request](https://goteleport.com/docs/identity-governance/access-requests.md) by UUID
- a bot instance ID (for Machine & Workload Identity bots)
- a join token name (for Machine & Workload Identity bots using a [delegated join method](https://goteleport.com/docs/reference/deployment/join-methods.md#delegated-join-methods))

## How it works

A lock is a dynamic Teleport resource stored on the Teleport Auth Service backend. Teleport services implement a lock watcher that subscribes to Auth Service events related to lock creation. When these services receive a notification that a lock has been created or modified, they enact safeguards to prevent various operations, e.g., preventing access from a locked user.

## Prerequisites

- A running Teleport cluster. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/get-started/deploy-community.md).

- The `tctl` and `tsh` clients.

  Installing `tctl` and `tsh` clients

  1. Determine the version of your Teleport cluster. The `tctl` and `tsh` clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at `/v1/webapi/find` and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
     ```

  2. Follow the instructions for your platform to install `tctl` and `tsh` clients:

     **Mac**

     Download the signed macOS .pkg installer for Teleport, which includes the `tctl` and `tsh` clients:

     ```
     $ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
     ```

     In Finder double-click the `pkg` file to begin installation.

     ---

     DANGER

     Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/installation.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

* To check that you can connect to your Teleport cluster, sign in with `tsh login`, then verify that you can run `tctl` commands using your current credentials. For example, run the following command, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and email\@example.com to your Teleport username:
  ```
  $ tsh login --proxy=teleport.example.com --user=email@example.com
  $ tctl status
  Cluster  teleport.example.com
  Version  19.0.0-dev
  CA pin   sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
  ```
  If you can connect to the cluster and run the `tctl status` command, you can use your current credentials to run subsequent `tctl` commands from your workstation. If you host your own Teleport cluster, you can also run `tctl` commands on the computer that hosts the Teleport Auth Service for full permissions.

## Step 1/2. Create a lock

You can create a new lock with the `tctl lock` command. Specify the lock target with one of the following options:

**Username**

```
$ tctl lock --user=foo@example.com --message="Suspicious activity." --ttl=10h
Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```

**Role**

All users with assigned roles matching the target role will be locked.

```
$ tctl lock --role=contractor --message="All contractor access is disabled for 10h." --ttl=10h
Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```

**Trusted device**

All connections initiated from a device matching the device ID will be locked.

```
$ tctl lock --device 9cdfc0ad-64b7-4d9c-9342-50e97f418ba0 --message="Compromised device" --ttl=48h
Created a lock with name "5444970a-39a0-4814-968d-e58b4a8fa686".
```

**Multi-factor device**

All connections initiated with per-session MFA matching the device ID will be locked.

```
$ tctl lock --mfa-device=d6c06a18-e147-4232-9dfe-6f83a28d5850 --message="All contractor access is disabled for 10h." --ttl=10h
Created a lock with name "d6c06a18-e147-4232-9dfe-6f83a28d5850".
```

**Agent**

All connections to the specified agent will be locked and the agent will be excluded from the Teleport cluster.

```
$ tctl lock --server-id=363256df-f78a-4d99-803c-bae19da9ede4 --message="The server running the Kubernetes Service and Database Service is under investigation." --ttl=10h
Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```

**Windows Desktop**

All connections to the specified Windows Desktop will be locked.

```
$ tctl lock --windows-desktop=WIN-FMPFM5UF1SS-teleport-example-com --ttl=10h
Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```

**Access request**

All connections using elevated privileges from the matching Access Request will be locked.

```
$ tctl lock --access-request=261e80c5-357b-4c43-9b67-40a6bc4c6e4d --ttl=24h
Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```

**Machine & Workload Identity Bot**

The most appropriate locking target for a Machine & Workload Identity bot depends on its join method.

For [delegated join methods](https://goteleport.com/docs/reference/deployment/join-methods.md#secret-vs-delegated), it's best to target the specific join token the bot is using to join:

```
$ tctl lock --join-token=example-token-name
```

The join token name cannot be targeted for bots joined using the `token` join method, so it's best to use the [bot instance ID](https://goteleport.com/docs/reference/architecture/machine-id-architecture.md#bot-instances):

```
$ tctl lock --bot-instance-id aabbccdd-1234-5678-0000-3b04d7d03acc
```

In all cases, you may also target the bot user, which will lock all instances of a bot that share the same underlying user:

```
$ tctl lock --user bot-example
```

Troubleshooting: failed to create a lock?

If your user is missing a lock permission, you will get an error when creating a lock:

```
ERROR: access denied to perform action "create" on "lock"

```

Define a role `locksmith`:

```
kind: role
version: v5
metadata:
  name: locksmith
spec:
  allow:
    rules:
      - resources: [lock]
        verbs: [list, create, read, update, delete]

```

Create the role:

```
$ tctl create -f locksmith.yaml
role 'locksmith' has been created
```

---

TIP

You can also create and edit roles using the Web UI. Go to **Access -> Roles** and click **Create New Role** or pick an existing role to edit.

---

Assign the `locksmith` role to your Teleport user by running the appropriate commands for your authentication provider:

**Local User**

1. Retrieve your local user's roles as a comma-separated list:

   ```
   $ ROLES=$(tsh status -f json | jq -r '.active.roles | join(",")')
   ```

2. Edit your local user to add the new role:

   ```
   $ tctl users update $(tsh status -f json | jq -r '.active.username') \
     --set-roles "${ROLES?},locksmith"
   ```

3. Sign out of the Teleport cluster and sign in again to assume the new role.

**GitHub**

1. Open your `github` authentication connector in a text editor:

   ```
   $ tctl edit github/github
   ```

2. Edit the `github` connector, adding `locksmith` to the `teams_to_roles` section.

   The team you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the team must include your user account and should be the smallest team possible within your organization.

   Here is an example:

   ```
     teams_to_roles:
       - organization: octocats
         team: admins
         roles:
           - access
   +       - locksmith

   ```

3. Apply your changes by saving and closing the file in your editor.

4. Sign out of the Teleport cluster and sign in again to assume the new role.

**SAML**

1. Retrieve your `saml` configuration resource:

   ```
   $ tctl get --with-secrets saml/mysaml > saml.yaml
   ```

   Note that the `--with-secrets` flag adds the value of `spec.signing_key_pair.private_key` to the `saml.yaml` file. Because this key contains a sensitive value, you should remove the saml.yaml file immediately after updating the resource.

2. Edit `saml.yaml`, adding `locksmith` to the `attributes_to_roles` section.

   The attribute you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the group must include your user account and should be the smallest group possible within your organization.

   Here is an example:

   ```
     attributes_to_roles:
       - name: "groups"
         value: "my-group"
         roles:
           - access
   +       - locksmith

   ```

3. Apply your changes:

   ```
   $ tctl create -f saml.yaml
   ```

4. Sign out of the Teleport cluster and sign in again to assume the new role.

**OIDC**

1. Retrieve your `oidc` configuration resource:

   ```
   $ tctl get oidc/myoidc --with-secrets > oidc.yaml
   ```

   Note that the `--with-secrets` flag adds the value of `spec.signing_key_pair.private_key` to the `oidc.yaml` file. Because this key contains a sensitive value, you should remove the oidc.yaml file immediately after updating the resource.

2. Edit `oidc.yaml`, adding `locksmith` to the `claims_to_roles` section.

   The claim you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the group must include your user account and should be the smallest group possible within your organization.

   Here is an example:

   ```
     claims_to_roles:
       - name: "groups"
         value: "my-group"
         roles:
           - access
   +       - locksmith

   ```

3. Apply your changes:

   ```
   $ tctl create -f oidc.yaml
   ```

4. Sign out of the Teleport cluster and sign in again to assume the new role.

With a lock in force, all established connections involving the lock's target get terminated while any new requests are rejected.

Errors returned and warnings logged in this situation feature a message of the form:

```
lock targeting User:"foo@example.com" is in force: Suspicious activity.

```

---

NOTE

You can tweak the message returned to a user with `--message` parameter:

```
$ tctl lock --user=foo@example.com --message="Please come back tomorrow." --ttl=24h
```

---

Details

Under the hood: Lock resource and expiration

Note that without specifying `--ttl` or `--expires`, the created lock remains in force until explicitly removed with `tctl rm`. Refer to `tctl lock --help` for the list of all supported parameters.

Under the hood, `tctl lock` creates a resource:

```
kind: lock
version: v2
metadata:
  name: dc7cee9d-fe5e-4534-a90d-db770f0234a1
spec:
  target:
    user: foo@example.com
  message: "Suspicious activity."
  expires: "2021-08-14T22:27:00Z"  # RFC3339 format

```

The `kind: lock` resources can also be created and updated using `tctl create` as per usual. See the [Admin Guide](https://goteleport.com/docs/reference/infrastructure-as-code/teleport-resources.md) for more details.

## Step 2/2. List and delete active locks

Use `tctl get` command to list all active locks:

```
$ tctl get locks
```

Delete a lock resource:

```
$ tctl rm locks/24679348-baff-4987-a2cd-e820ab7f9d2b
lock "24679348-baff-4987-a2cd-e820ab7f9d2b" has been deleted
```

Deleting a lock will allow new sessions or host connections.

## Next steps: Locking modes

If a Teleport Node or Proxy Service cannot properly synchronize its local lock view with the backend, there is a decision to be made about whether to rely on the last known locks. This decision strategy is encoded as one of the two modes:

- `strict` mode causes all interactions to be terminated when the locks are not guaranteed to be up to date
- `best_effort` mode keeps relying on the most recent locks

**Self-Hosted**

The cluster-wide mode defaults to `best_effort`. You can set up the default locking mode via API or CLI using a `cluster_auth_preference` resource or static configuration file.

If your Auth Service configuration (`/etc/teleport.yaml` by default) contains an `auth_service.authentication` section, edit the Teleport configuration file to contain the following:

```
auth_service:
    authentication:
        locking_mode: best_effort

```

Restart or redeploy the Auth Service for the change to take effect.

If not, edit your cluster authentication preference resource:

```
$ tctl edit cap
```

Adjust the file in your editor to include the following:

```
kind: cluster_auth_preference
metadata:
  name: cluster-auth-preference
spec:
  locking_mode: best_effort
version: v2

```

Save and close your editor to apply your changes.

**Teleport Enterprise (Cloud)**

The cluster-wide mode defaults to `best_effort`. You can set up the default locking mode via API or CLI using a `cluster_auth_preference` resource:

```
$ tctl edit cap
```

Adjust the file in your editor to include the following:

```
kind: cluster_auth_preference
metadata:
  name: cluster-auth-preference
spec:
  locking_mode: best_effort
version: v2

```

Save and close your editor to apply your changes.

It is also possible to configure the locking mode for a particular role:

```
kind: role
version: v5
metadata:
    name: example-role-with-strict-locking
spec:
    options:
       lock: strict

```

When none of the roles involved in an interaction specify the mode or when there is no user involved, the mode is taken from the cluster-wide setting.

With multiple potentially conflicting locking modes (the cluster-wide default and the individual per-role settings) a single occurrence of `strict` suffices for the local lock view to become evaluated strictly.
