diff --git a/docs/config.json b/docs/config.json index ff9a565374644..3f6cf8677ebab 100644 --- a/docs/config.json +++ b/docs/config.json @@ -60,6 +60,11 @@ "oss" ] }, + { + "title": "Self-Hosted Kubernetes", + "slug": "/upgrading/self-hosted-kubernetes/", + "forScopes": ["enterprise", "oss"] + }, { "title": "Self-Hosted Automatic Upgrades", "slug": "/upgrading/self-hosted-automatic-agent-updates/", @@ -847,6 +852,14 @@ "title": "Using Dynamic Resources", "slug": "/management/dynamic-resources/", "entries": [ + { + "title": "Managing Users and Roles", + "slug": "/management/dynamic-resources/user-and-role/" + }, + { + "title": "Managing Access Lists", + "slug": "/management/dynamic-resources/access-list/" + }, { "title": "Kubernetes Operator", "slug": "/management/dynamic-resources/teleport-operator/" @@ -1988,6 +2001,10 @@ "title": "Signals", "slug": "/reference/signals/" }, + { + "title": "User Types", + "slug": "/reference/user-types/" + }, { "title": "Helm Charts", "slug": "/reference/helm-reference/", diff --git a/docs/cspell.json b/docs/cspell.json index 05e5c77ddd1b1..108a966197577 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -237,6 +237,7 @@ "Zqar", "Zrpsaln", "abcdefghijklm", + "accesslist", "aclfile", "acmecorp", "acpi", @@ -798,6 +799,8 @@ "tctl", "teleadmins", "telenode", + "teleportaccesslist", + "teleportaccesslists", "teleportauditlogssofailed", "teleportblob", "teleportdemo", @@ -808,8 +811,9 @@ "teleporters", "teleportinfra", "teleportproxy", - "teleportroles", + "teleportrolev", "teleportrolesv", + "teleportuser", "teleportusers", "teleportversionoverride", "teleportyaml", diff --git a/docs/img/management/access-list-web-ui.png b/docs/img/management/access-list-web-ui.png new file mode 100644 index 0000000000000..2e1b1b0cd2e99 Binary files /dev/null and b/docs/img/management/access-list-web-ui.png differ diff --git a/docs/img/management/check-users-web-ui.png b/docs/img/management/check-users-web-ui.png new file mode 100644 index 0000000000000..1f291b650a84f Binary files /dev/null and b/docs/img/management/check-users-web-ui.png differ diff --git a/docs/pages/includes/diagnostics/kubernetes-operator-troubleshooting.mdx b/docs/pages/includes/diagnostics/kubernetes-operator-troubleshooting.mdx index a02bc90c39999..308fac0ae45af 100644 --- a/docs/pages/includes/diagnostics/kubernetes-operator-troubleshooting.mdx +++ b/docs/pages/includes/diagnostics/kubernetes-operator-troubleshooting.mdx @@ -1,3 +1,5 @@ +### The CustomResources (CRs) are not reconciled + The Teleport Operator watches for new resources or changes in Kubernetes. When a change happens, it triggers the reconciliation loop. This loop is in charge of validating the resource, checking if it already exists in Teleport @@ -37,24 +39,58 @@ Here `SuccessfullyReconciled` is `False` and the error is `role my-non-existing- If the status is not present or does not give sufficient information to solve the issue, check the operator logs: -```shell -$ kubectl logs deploy/ -``` - - In case of multi-replica deployments, only one operator instance is running - the reconciliation loop. This operator is called the leader and is the only - one producing reconciliation logs. The other operator instances are waiting - with the following log: +### The CR doesn't have a status - ``` - leaderelection.go:248] attempting to acquire leader lease teleport/431e83f4.teleport.dev... - ``` +1. Check if the CR is in the same namespace as the operator. The operator only + watches for resource in its own namespace. +1. Check if the operator pods are running and healthy: + ```code + kubectl get pods -n "$OPERATOR_NAMESPACE"` + ``` +1. Check the operator logs: + ```code + $ kubectl logs deploy/ -n "$OPERATOR_NAMESPACE" + ``` + + + In case of multi-replica deployments, only one operator instance is running + the reconciliation loop. This operator is called the leader and is the only + one producing reconciliation logs. The other operator instances are waiting + with the following log: + + ``` + leaderelection.go:248] attempting to acquire leader lease teleport/431e83f4.teleport.dev... + ``` + + To diagnose reconciliation issues, you will have to inspect all pods to find + the one reconciling the resources. + - To diagnose reconciliation issues, you will have to inspect all pods to find - the one reconciling the resources. - +### I cannot delete the Kubernetes CR -If the Kubernetes resource has no status update and the operator does not produce -any logs regarding the resource, please check if the resource lives in the same -namespace as the operator. The operator only watches for resource in its own namespace. +The operator protects Kubernetes CRs from deletion with a finalizer. +It will not allow the CR to be deleted until the Teleport resource is deleted as +well, this is a safety to avoid leaving dangling resources and potentially grant +unintentional access. + +There might be some reasons causing Teleport to refuse a resource deletion, the +most frequent one is if another resource depends on it. For example: you cannot +delete a role if it is still assigned to a user. + +If this happens, the operator will report the error sent by Teleport in its log. + +To resolve this lock, you can either: +- resolve the dependency issue so the resource gets successfully deleted in + Teleport. In the role example, this would imply removing any mention of the + role from the various users who had it. +- patch the Kubernetes CR to remove the finalizers. This will tell Kubernetes to + stop waiting for the operator deletion and remove the CR. If you do this, the + CR will be removed but the Teleport resource will remain. The operator will + never attempt to remove it again. + + For example, if the role is named `my-role`: + + ```code + kubectl patch TeleportRole my-role -p '{"metadata":{"finalizers":null}}' --type=merge + ``` diff --git a/docs/pages/management/dynamic-resources.mdx b/docs/pages/management/dynamic-resources.mdx index 209856531eb08..d74b2eef65f39 100644 --- a/docs/pages/management/dynamic-resources.mdx +++ b/docs/pages/management/dynamic-resources.mdx @@ -59,6 +59,11 @@ to manipulate cluster resources stored on the Auth Service backend. The design of Teleport's configuration interface makes it well suited for infrastructure-as-code and GitOps approaches. +You can get started with `tctl`, the Terraform Provider, and the Kubernetes +Operator by following: +- the ["Managing Users and Roles with IaC" guide](./dynamic-resources/user-and-role.mdx) +- the ["Creating Access Lists with IaC" guide](./dynamic-resources/access-list.mdx) + For more information on Teleport roles, including the `internal.logins` trait we use in these example roles, see the [Teleport Access Controls Reference](../access-controls/reference.mdx). @@ -211,6 +216,8 @@ Here are possible values of the `teleport.dev/origin` label: - `defaults` - `config-file` - `dynamic` +- `terraform` +- `kubernetes` When the Auth Service starts up, it looks up the values of static configuration fields that correspond to fields in dynamic configuration resources. If any of diff --git a/docs/pages/management/dynamic-resources/access-list.mdx b/docs/pages/management/dynamic-resources/access-list.mdx new file mode 100644 index 0000000000000..da651b1c4cd95 --- /dev/null +++ b/docs/pages/management/dynamic-resources/access-list.mdx @@ -0,0 +1,300 @@ +--- +title: Creating Access Lists with IaC +description: Use Infrastructure-as-Code tooling to create Teleport AccessLists. +--- + +Access Lists allow Teleport users to be granted long-term access to resources +managed within Teleport. With Access Lists, administrators can regularly audit and control membership to specific roles and +traits, which then tie easily back into Teleport's existing RBAC system. + +In this guide, we'll follow up +on [the IaC users and roles guide](./user-and-role.mdx) by allowing users with +the `manager` role to grant the `support-engineer` role to users meeting +specific criteria. + +Please note that Access Lists can be managed via IaC but Access List memberships +cannot. The goal of Access Lists is to decentralize granting and reviewing +access. By allowing managers to grant access within specific guidelines and +automatically enforcing review, users can request common access rights without +having to go through the centralized team managing the Teleport IaC. +This reduces the load on the centralized IaC/security team, ensures the access +reviewer is aware of the context, reduces the request resolution time, and +ensures access grants are periodically reviewed. + +## Prerequisites + +To follow this guide, you must follow +first [the basic users and roles IaC guide](./user-and-role.mdx). We will reuse +its users and roles for our Access List. + +## Step 1/3 - Write manifests + +### Write the privileged role manifest + +We will create a new role `support-engineer` that grants access to production +servers. The `engineer` role from the previous guide was only granting access to +`dev` and `staging` servers. + + + + + +Create the following `privileged-role.yaml` file: + +```yaml +kind: role +version: v7 +metadata: + name: support-engineer +spec: + allow: + logins: ['root', 'ubuntu', '{{internal.logins}}'] + node_labels: + 'env': ['production'] +``` + + + + +Create the following `privileged-role.yaml` file: + +```yaml +apiVersion: resources.teleport.dev/v1 +kind: TeleportRoleV7 +metadata: + name: support-engineer +spec: + allow: + logins: [ 'root', 'ubuntu', '{{internal.logins}}' ] + node_labels: + 'env': [ 'production' ] +``` + + + + +Create the following `privileged-role.tf` file: + +```hcl +resource "teleport_role" "support-engineer" { + version = "v7" + metadata = { + name = "support-engineer" + } + + spec = { + allow = { + logins = ["root", "ubuntu", "{{internal.logins}}"] + node_labels = { + env = ["production"] + } + } + } +} +``` + + + + +### Write the Access List manifest + +In this step we'll create an Access List that allows users with the `manager` +role such as `alice` to grant access to production to users with the `engineer` +role. + + + + +Create the following `accesslist.yaml` file: + +```yaml +version: v1 +kind: access_list +metadata: + name: support-engineers +spec: + title: "Production access for support engineers" + audit: + recurrence: + frequency: 6months + description: "Use this Access List to grant access to production to your engineers enrolled in the support rotation." + owners: + - description: "manager of NA support team" + name: alice + ownership_requires: + roles: + - manager + grants: + roles: + - support-engineer + membership_requires: + roles: + - engineer +``` + + + + +Create the following `accesslist.yaml` file: + +```yaml +apiVersion: resources.teleport.dev/v1 +kind: TeleportAccessList +metadata: + name: support-engineers +spec: + title: "Production access for support engineers" + description: "Use this Access List to grant access to production to your engineers enrolled in the support rotation." + audit: + recurrence: + frequency: 6months + owners: + - description: "manager of NA support team" + name: alice + ownership_requires: + roles: + - manager + grants: + roles: + - support-engineer + membership_requires: + roles: + - engineer +``` + + + + +Create the following `accesslist.tf` file: + +```hcl +resource "teleport_access_list" "support-engineers" { + header = { + version = "v1" + metadata = { + name = "support-engineers" + } + } + + spec = { + title = "Production access for support engineers" + description = "Use this Access List to grant access to production to your engineers enrolled in the support rotation." + audit = { + recurrence = { + frequency = 6 + } + } + owners = [ + { + description = "manager of NA support team" + name = "alice" + } + ] + ownership_requires = { + roles = ["manager"] + } + grants = { + roles = ["support-engineer"] + } + membership_requires = { + roles = ["engineer"] + } + } +} +``` + + + + +## Step 2/3 - Apply the manifests + + + + +```code +$ tctl create -f privileged-role.yaml +role 'support-engineer' has been created + +$ tctl create -f accesslist.yaml +Access list "support-engineers" has been created +``` + + +The user resource depends on roles. You must create roles before users as a user +with a non-existing role is invalid and will be rejected by Teleport. + + + + + +Create the Kubernetes CRs with the following commands: + +```code +$ kubectl apply -n "$OPERATOR_NAMESPACE" -f privileged-role.yaml +teleportrolev7.resources.teleport.dev/support-engineer created + +$ kubectl apply -n "$OPERATOR_NAMESPACE" -f accesslist.yaml +teleportaccesslist.resources.teleport.dev/support-engineers +``` + + + + +```code +$ terraform plan +[...] +Plan: 2 to add, 0 to change, 0 to destroy. + +$ terraform apply +teleport_access_list.support-engineers: Creating... +teleport_role.support-engineer: Creating... +teleport_role.support-engineer: Creation complete after 0s [id=support-engineer] +teleport_access_list.support-engineers: Creation complete after 0s [id=support-engineers] +``` + + + + +## Step 3/3 - Log in as `alice` and grant access to `bob` + +Now, you created an Access List allowing `alice` to grant the `support-engineer` +role to its engineers. + +You can log in as alice and add `bob` to the `support-engineers` Access List. + + + + +Login as `alice` in the web UI, open the management panel and select the +"Access Lists" tab. Your Access List should be displayed, open it, choose "Enroll +members" and add `bob`. + +![Screenshot of the web UI showing the Access List and the "Enroll Member" button](../../../img/management/access-list-web-ui.png) + + + + +Login as `alice` with `tsh`, then add bob to the Access List: + +```code +# login as alice +$ tsh login --proxy : --user alice + +# tctl acl users add [] [] +$ tctl acl users add support-engineers bob "" "Bob is now part of the on-call support rotation" +``` + +Finally, list the Access List members: +```code +$ tctl acl users ls support-engineers +Members of support-engineers: +- bob +``` + + + + +## Next steps + +You can see all supported Access List fields +[in the Access List reference](../../access-controls/access-lists/reference.mdx). diff --git a/docs/pages/management/dynamic-resources/teleport-operator-helm.mdx b/docs/pages/management/dynamic-resources/teleport-operator-helm.mdx index 2a236d5fb989c..5c5850a252168 100644 --- a/docs/pages/management/dynamic-resources/teleport-operator-helm.mdx +++ b/docs/pages/management/dynamic-resources/teleport-operator-helm.mdx @@ -35,7 +35,7 @@ $ kubectl cluster-info ``` -## Step 1/3. Install teleport-cluster Helm chart with the operator +## Step 1/2. Install teleport-cluster Helm chart with the operator (!docs/pages/kubernetes-access/helm/includes/helm-repo-add.mdx!) @@ -86,101 +86,26 @@ $ helm install teleport-cluster teleport/teleport-cluster \ This command installs the required Kubernetes CRDs and deploys the Teleport Kubernetes Operator next to the Teleport cluster. All resources (except CRDs, which are cluster-scoped) are created in the `teleport-cluster` namespace. -## Step 2/3. Manage Teleport users and roles using `kubectl` +## Step 2/2. Validate the cluster and operator are running and healthy -Create a manifest called `teleport-resources.yaml` that describes two custom resources: a `TeleportUser` and a `TeleportRole`: - -```yaml -apiVersion: resources.teleport.dev/v1 -kind: TeleportRoleV7 -metadata: - name: myrole -spec: - allow: - rules: - - resources: ['user', 'role'] - verbs: ['list','create','read','update','delete'] ---- -apiVersion: resources.teleport.dev/v2 -kind: TeleportUser -metadata: - name: myuser -spec: - roles: ['myrole'] -``` - - - Kubernetes validates all custom resource names to follow RFC 1123, which includes specifications for hostnames. - This requires the `metadata.name` field of Teleport resources controlled by the operator to consist of lowercase alphanumeric - characters, `-` or `.`, and to start and end with an alphanumeric character. - - -Apply the manifests to the Kubernetes cluster: - -```code -$ kubectl apply -n -f teleport-resources.yaml -``` - -List the created Kubernetes resources: - -```code -$ kubectl get teleportrolesv7 -n -# NAME AGE -# myrole 10m - -$ kubectl get teleportusers -n -# NAME AGE -# myuser 10m -``` - -Check the user `myuser` has been created in Teleport and has been granted the role `myrole`: ```code -$ AUTH_POD=$(kubectl get pods -n -l app=teleport-cluster -o jsonpath='{.items[0].metadata.name}') -$ kubectl exec -it "$AUTH_POD" -c teleport -- tctl users ls -# User Roles -# ----------------------------- ----------------------------- -# bot-teleport-operator-sidecar bot-teleport-operator-sidecar -# myuser myrole -``` - -At this point the Teleport Kubernetes Operator is functional and Teleport users and roles can be managed from -Kubernetes. +$ kubectl get deployments -n +# -## Step 3/3. Explore the Teleport CRDs - -Available fields can be browsed with `kubectl explain` in a cluster with Teleport CRDs installed. -For example the command: -```code -$ kubectl explain teleportroles.spec +$ kubectl get pods -n +# ``` -Returns the following fields: -```shell -KIND: TeleportRoleV7 -VERSION: resources.teleport.dev/v1 -RESOURCE: spec - -DESCRIPTION: - Role resource definition v7 from Teleport +## Next steps -FIELDS: - allow - Allow is the set of conditions evaluated to grant access. +Follow [the user and role IaC guide](./user-and-role.mdx) to use your newly +deployed Teleport Kubernetes Operator to create Teleport users and grant them +roles. - deny - Deny is the set of conditions evaluated to deny access. Deny takes priority - over allow. +Helm Chart parameters are documented in the [`teleport-cluster` Helm chart reference](../../reference/helm-reference/teleport-cluster.mdx). - options - Options is for OpenSSH options like agent forwarding. -``` +See the [Helm Deployment guides](../../deploy-a-cluster/helm-deployments.mdx) detailing specific setups like running Teleport on AWS or GCP. ## Troubleshooting (!docs/pages/includes/diagnostics/kubernetes-operator-troubleshooting.mdx!) - -## Next steps - -Helm Chart parameters are documented in the [`teleport-cluster` Helm chart reference](../../reference/helm-reference/teleport-cluster.mdx). - -See the [Helm Deployment guides](../../deploy-a-cluster/helm-deployments.mdx) detailing specific setups like running Teleport on AWS or GCP. diff --git a/docs/pages/management/dynamic-resources/teleport-operator-standalone.mdx b/docs/pages/management/dynamic-resources/teleport-operator-standalone.mdx index 4fc37b594e5cd..f146258278e2d 100644 --- a/docs/pages/management/dynamic-resources/teleport-operator-standalone.mdx +++ b/docs/pages/management/dynamic-resources/teleport-operator-standalone.mdx @@ -9,7 +9,7 @@ If your Teleport cluster is deployed using the `teleport-cluster` Helm chart, yo ## Prerequisites -(!docs/pages/includes/self-hosted-prereqs-tabs.mdx!) +(!docs/pages/includes/edition-prereqs-tabs.mdx!) - a Kubernetes cluster. You must be able to create/read Namespace, ServiceAccount, Deployment, Secret, Role, RoleBinding and CustomResourceDefinition resources. @@ -34,7 +34,7 @@ $ kubectl cluster-info ``` -### Step 1/4 - Create the operator role +### Step 1/4. Create the operator role In this step we create the role the operator uses to interact with Teleport resources. @@ -51,7 +51,7 @@ resources, you will need to re-apply the operator role manifest. This will grant the operator access to the new resources. -### Step 2/4 - Create the operator join token +### Step 2/4. Create the operator join token The join token is used by the operator on each startup to join the Teleport cluster and retrieve its client certificates. @@ -91,7 +91,7 @@ To establish trust between the connecting operator and Teleport, we are delegati $ export CLUSTER_NAME="$(tctl status | awk '/Cluster/ {print $2}')" ``` -### Step 3/4 - Create the operator bot +### Step 3/4. Create the operator bot In Teleport, a bot is a resource allowing a machine to access Teleport. Create a bot for the operator with the following command: @@ -100,7 +100,7 @@ Create a bot for the operator with the following command: $ tctl bots add operator --token operator-bot --roles operator ``` -### Step 4/4 - Deploy the operator in the Kubernetes cluster +### Step 4/4. Deploy the operator in the Kubernetes cluster At this point, you can configure and run the operator: @@ -127,11 +127,15 @@ At this point, you can configure and run the operator: ```code $ kubectl get pods -n teleport-iac ``` + +## Next steps -## Troubleshooting +Follow [the user and role IaC guide](./user-and-role.mdx) to use your newly +deployed Teleport Kubernetes Operator to create Teleport users and grant them +roles. -(!docs/pages/includes/diagnostics/kubernetes-operator-troubleshooting.mdx!) +Helm Chart parameters are documented in the [`teleport-operator` Helm chart reference](../../reference/helm-reference/teleport-operator.mdx). -## Next steps +## Troubleshooting -Helm Chart parameters are documented in the [`teleport-operator` Helm chart reference](../../reference/helm-reference/teleport-operator.mdx). +(!docs/pages/includes/diagnostics/kubernetes-operator-troubleshooting.mdx!) diff --git a/docs/pages/management/dynamic-resources/teleport-operator.mdx b/docs/pages/management/dynamic-resources/teleport-operator.mdx index 3864f031547f7..e4ab426ee9ccd 100644 --- a/docs/pages/management/dynamic-resources/teleport-operator.mdx +++ b/docs/pages/management/dynamic-resources/teleport-operator.mdx @@ -51,4 +51,5 @@ follow [the standalone operator guide](./teleport-operator-standalone.mdx). ## Next steps -Check out [access controls documentation](../../access-controls/introduction.mdx) +- Follow the ["Managing users and roles with IaC" guide](./user-and-role.mdx). +- Check out [access controls documentation](../../access-controls/introduction.mdx). diff --git a/docs/pages/management/dynamic-resources/terraform-provider.mdx b/docs/pages/management/dynamic-resources/terraform-provider.mdx index 6e4611c142ada..f5a5c67287ec7 100644 --- a/docs/pages/management/dynamic-resources/terraform-provider.mdx +++ b/docs/pages/management/dynamic-resources/terraform-provider.mdx @@ -4,10 +4,11 @@ description: How to manage dynamic resources using the Teleport Terraform provid videoBanner: YgNHD4SS8dg --- -This guide demonstrates how to: +This guide demonstrates how to: Set up the Terraform provider for Teleport on +Linux and macOS. -- Set up the Terraform provider for Teleport on Linux and macOS. -- Configure Teleport users and roles using the Terraform provider. +For instructions on managing users and roles via Terraform, read +the ["Managing users and roles with IaC" guide](./user-and-role.mdx). For instructions on managing the Teleport dynamic resources as code using GitOps, read the guide to using the Teleport Terraform provider with [Spacelift @@ -79,6 +80,7 @@ To prepare credentials for a local Teleport user: - token - trusted_cluster - user + - access_list verbs: ['list','create','read','update','delete'] version: v7 --- @@ -96,7 +98,9 @@ To prepare credentials for a local Teleport user: 1. Create the `terraform` user and role by running the following command: ```code - $ tctl create terraform.yaml + $ tctl create -f terraform.yaml + role 'terraform' has been created + user "terraform" has been created ``` The `terraform` user can't sign in to get credentials, so you must have another user @@ -125,7 +129,8 @@ the following content into the `terraform-impersonator.yaml` file: 1. Create the `terraform-impersonator` role by running the following command: ```code - $ tctl create terraform-impersonator.yaml + $ tctl create -f terraform-impersonator.yaml + role 'terraform-impersonator' has been created ``` 1. (!docs/pages/includes/add-role-to-user.mdx role="terraform-impersonator"!) @@ -142,24 +147,25 @@ the following content into the `terraform-impersonator.yaml` file: To prepare a Terraform configuration file: -1. Create a new file called `main.tf` and open it in an editor. +1. Create a new file called `provider.tf` and open it in an editor. -1. Define an example user and role using Terraform by pasting the following content into the `main.tf` file: +1. Use the Teleport Terraform provider and connect it to your Teleport cluster + by pasting the following content into the `provider.tf` file: ```hcl - (!examples/resources/terraform/terraform-user-role-cloud.tf!) + (!examples/resources/terraform/provider-cloud.tf!) ``` ```hcl - (!examples/resources/terraform/terraform-user-role-self-hosted.tf!) + (!examples/resources/terraform/provider-self-hosted.tf!) ``` -## Step 3/3. Apply the configuration +## Step 3/3. Validate the configuration To apply the configuration: @@ -167,18 +173,18 @@ To apply the configuration: ```code $ ls - # main.tf terraform-identity terraform-impersonator.yaml terraform.yaml + # provider.tf terraform-identity terraform-impersonator.yaml terraform.yaml ``` -1. Initialize the working directory that contains Terraform configuration files by running the -following command: +1. Initialize the working directory that contains Terraform configuration files + by running the following command: ```code $ terraform init ``` 1. Execute the Terraform plan defined in the configuration file by running the -following command: + following command: ```code $ terraform apply @@ -186,5 +192,7 @@ following command: ## Next steps +- Follow [the user and role IaC guide](./user-and-role.mdx) to use the Terraform + Provider to create Teleport users and grant them roles. - Explore the full list of supported [Terraform provider resources](../../reference/terraform-provider.mdx). - Read more about [impersonation](../../access-controls/guides/impersonation.mdx). diff --git a/docs/pages/management/dynamic-resources/user-and-role.mdx b/docs/pages/management/dynamic-resources/user-and-role.mdx new file mode 100644 index 0000000000000..a45308852bf8b --- /dev/null +++ b/docs/pages/management/dynamic-resources/user-and-role.mdx @@ -0,0 +1,492 @@ +--- +title: Managing Users And Roles With IaC +description: Use infrastructure-as-code tooling to create Teleport users and roles. +--- + +In this guide, you will see how to create users and grant them roles through +infrastructure as code (IaC). Teleports supports three ways to dynamically +create resources from code: + +- The Teleport Kubernetes Operator, which allows you to manage Teleport resources + from Kubernetes +- The Teleport Terraform Provider, which allows you to manage Teleport resources + via Terraform +- The `tctl` CLI, which allows you to manage Teleport resources from your local + computer or your CI environment + +## Prerequisites + +To follow this guide, you must have: + + + + +(!docs/pages/includes/edition-prereqs-tabs.mdx!) + + + + +A running operator by following either: +- [the guide to enable the operator in the `teleport-cluster` Helm chart](./teleport-operator-helm.mdx). +- [the guide to setup a standalone operator](./teleport-operator-standalone.mdx). + +You must also set the namespace in which you deployed the operator as this is +the namespace where you will deploy the CustomResources: + +```code +# for operators deployed with the `teleport-cluster` Helm chart +$ export OPERATOR_NAMESPACE="teleport-cluster" + +# for standalone operators +$ export OPERATOR_NAMESPACE="teleport-iac" +``` + + + + +A functional Teleport Terraform provider by following [the Terraform provider guide](./terraform-provider.mdx). + + + + +## Step 1/4. Write manifests + +In this step, we'll write text files describing the resources we want in +Teleport. Those files are called manifests and their syntax will vary based on +the IaC tooling you'll use. + +Those manifests are typically versioned in a shared revision system like git. +This allows you to keep track of all changes, follow standard code review +procedures before changing resources in Teleport, and quickly redeploy your +Teleport instance if needed. + +### Write role manifests + +We will create 2 roles: + +- `manager` allows listing users and roles, as well as reviewing audit events and + session contents. +- `engineer` grants access to dev and staging servers. + + + + +Create the following `roles.yaml` file: + +```yaml +kind: role +version: v7 +metadata: + name: manager +spec: + allow: + rules: + - resources: ['user', 'role'] + verbs: ['list','read'] + - resources: ['session', 'event'] + verbs: ['list', 'read'] +--- +kind: role +version: v7 +metadata: + name: engineer +spec: + allow: + logins: ['root', 'ubuntu', '{{internal.logins}}'] + node_labels: + 'env': ['test', 'staging'] +``` + + + + +Create the following `roles.yaml` file: + +```yaml +apiVersion: resources.teleport.dev/v1 +kind: TeleportRoleV7 +metadata: + name: manager +spec: + allow: + rules: + - resources: ['user', 'role'] + verbs: ['list','read'] + - resources: ['session', 'event'] + verbs: ['list', 'read'] +--- +apiVersion: resources.teleport.dev/v1 +kind: TeleportRoleV7 +metadata: + name: engineer +spec: + allow: + logins: ['root', 'ubuntu', '{{internal.logins}}'] + node_labels: + 'env': ['test', 'staging'] +``` + + + Kubernetes validates all custom resource names to follow RFC 1123, which + includes specifications for hostnames. This requires the `metadata.name` field + of Teleport resources controlled by the operator to consist of lowercase + alphanumeric characters, `-` or `.`, and to start and end with an alphanumeric + character. + + + + + +Create the following `roles.tf` file: + +```hcl +resource "teleport_role" "manager" { + version = "v7" + metadata = { + name = "manager" + } + + spec = { + allow = { + rules = [ + { + resources = ["user", "role"] + verbs = ["list", "read"] + }, + { + resources = ["session", "event"] + verbs = ["list", "read"] + } + ] + } + } +} + +resource "teleport_role" "engineer" { + version = "v7" + metadata = { + name = "engineer" + } + + spec = { + allow = { + logins = ["root", "ubuntu", "{{internal.logins}}"] + node_labels = { + env = ["test", "staging"] + } + } + } +} +``` + + + + +### Write user manifests + +We will create 2 users: +- Bob, an engineer with the `engineer` role. +- Alice, an engineering manager with both `manager` and `engineer` roles. + + + Users created from manifests are local users, as opposed to users coming from + an external SAML/OIDC/GitHub Identity Provider (IdP). + + See [the user type reference](../../reference/user-types.mdx) for more details. + + + + + +Create the file `users.yaml` with the following content: + +```yaml +kind: user +version: v2 +metadata: + name: alice +spec: + roles: ['manager', 'engineer'] +--- +kind: user +version: v2 +metadata: + name: bob +spec: + roles: ['engineer'] +``` + + + + +Create the file `users.yaml` with the following content: + +```yaml +apiVersion: resources.teleport.dev/v2 +kind: TeleportUser +metadata: + name: alice +spec: + roles: ['manager', 'engineer'] +--- +apiVersion: resources.teleport.dev/v2 +kind: TeleportUser +metadata: + name: bob +spec: + roles: ['engineer'] +``` + + + Kubernetes validates all custom resource names to follow RFC 1123, which + includes specifications for hostnames. This requires the `metadata.name` field + of Teleport resources controlled by the operator to consist of lowercase + alphanumeric characters, `-` or `.`, and to start and end with an alphanumeric + character. + + + + + +Create the file `users.tf` with the following content: + +```hcl +resource "teleport_user" "alice" { + version = "v2" + metadata = { + name = "alice" + } + + spec = { + # referencing to the teleport_role resource name instead of using plain + # strings tells Terraform that the user depends on the role. Thanks to this, + # Terraform will create the role first and won't let you remove the role + # if it is still assigned to a user (which is illegal in Teleport). + roles = [ + teleport_role.manager.metadata.name, + teleport_role.engineer.metadata.name, + ] + } +} + +resource "teleport_user" "bob" { + version = "v2" + metadata = { + name = "bob" + } + + spec = { + roles = [teleport_role.engineer.metadata.name] + } +} +``` + + + + + +## Step 2/4. Apply all manifests + + + + +```code +$ tctl create -f roles.yaml +role 'manager' has been created +role 'engineer' has been created + +$ tctl create -f users.yaml +user "alice" has been created +user "bob" has been created +``` + + +The user resource depends on roles, you must create roles before users as a user +with a non-existing role is invalid and might be rejected by Teleport. + + + + + +```code +$ kubectl apply -n "$OPERATOR_NAMESPACE" -f roles.yaml +teleportrolev7.resources.teleport.dev/manager created +teleportrolev7.resources.teleport.dev/engineer created + +$ kubectl apply -n "$OPERATOR_NAMESPACE" -f users.yaml +teleportuser.resources.teleport.dev/alice created +teleportuser.resources.teleport.dev/bob created +``` + +List the created Kubernetes resources: + +```code +$ kubectl get teleportrolev7 -n "$OPERATOR_NAMESPACE" +# NAME AGE +# engineer 10m +# manager 10m + +$ kubectl get teleportusers -n "$OPERATOR_NAMESPACE" +# NAME AGE +# alice 10m +# bob 10m +``` + + + + +```code +$ terraform plan +[...] +Plan: 4 to add, 0 to change, 0 to destroy. + +$ terraform apply +teleport_role.engineer: Creating... +teleport_role.manager: Creating... +teleport_role.engineer: Creation complete after 0s [id=engineer] +teleport_role.manager: Creation complete after 0s [id=manager] +teleport_user.bob: Creating... +teleport_user.alice: Creating... +teleport_user.bob: Creation complete after 0s [id=bob] +teleport_user.alice: Creation complete after 0s [id=alice] + +Apply complete! Resources: 4 added, 0 changed, 0 destroyed. +``` + + + + +## Step 3/4. Validate users were created + +Now that the IaC tooling has run, we'll validate that the users were properly +created and granted the correct roles. + + + + +If you have UI access, connect to your Teleport cluster Web UI, open the +management panel, and select the "Users" tab. + +![Screenshot of the web UI listing alice and bob users](../../../img/management/check-users-web-ui.png) + +Two new users `alice` and `bob` should be present. + + + + +```code +$ tctl users ls +User Roles +----------------------------- ------------------------- +@teleport-access-approval-bot @teleport-access-approver +alice manager,engineer +bob engineer +bot-operator bot-operator + +# alternatively you can inspect the users details by doing +$ tctl get user/alice +kind: user +metadata: + id: 1704849160091933780 + labels: + teleport.dev/origin: kubernetes + name: alice +spec: + created_by: + time: "2024-01-10T01:12:40.088581806Z" + user: + name: bot-operator + expires: "0001-01-01T00:00:00Z" + roles: + - manager + - engineer + status: + is_locked: false + lock_expires: "0001-01-01T00:00:00Z" + locked_time: "0001-01-01T00:00:00Z" + recovery_attempt_lock_expires: "0001-01-01T00:00:00Z" +version: v2 +``` + + + + +## Step 4/4. Create a password reset link + +At this point, the local users have been created in Teleport. However, we never +specified any password or additional authentication factors. You must issue a +password reset link for the users to finish their Teleport registration and be +able to log in Teleport. + +User reset links contain single-use expiring tokens. Because of this, you cannot +follow the same declarative approach as for other Teleport resources and +generate them via a manifest. You need to create those tokens once after the +user creation, and securely send them to the end-user for them to register their +password/MFA. + +### Option 1: Reset via CLI +You can manually reset a user password via `tctl` by doing: + +```code +$ tctl users reset alice +User "alice" has been reset. Share this URL with the user to complete password reset, link is valid for 8h: +https://teleport.example.com:443/web/reset/05b420fdc784597cbbb1d2ba65697cd8 + +NOTE: Make sure teleport.example.com:443 points at a Teleport proxy which users can access. +``` + +### Option 2: Automating user reset + +If you have a way to securely send reset links to the users, you can build +automation to fit your organization's specific needs. For example: + +``` +$ tctl users reset alice --format=json | \ + jq '"Sending an email to " + .spec.user +" that contains the link: " + .spec.url' +``` + +You must replace the `jq` command by something that actually sends the link over +a secure channel. This channel will depend on your organization. It is usually a +direct message or an email. + + + +You can trigger your custom script on Terraform resource creation with +[the `local-exec` provisioner](https://developer.hashicorp.com/terraform/language/resources/provisioners/local-exec). + +```hcl +resource "teleport_user" "bob" { + version = v2 + metadata = { + name = "bob" + } + + spec = { + roles = [teleport_role.engineer.metadata.name] + } + + # on user creation, trigger a reset flow and send the link via + provisioner "local-exec" { + command = "tctl users reset alice --format=json | jq '\"Sending an email to \" + .spec.user +\" that contains the link: \" + .spec.url'" + } +} + +``` + + + +## Next steps + +- Allow users with the `manager` role to grant access to production servers to + some `engineers` via Access Lists. Manager will need to justify and review + granted access periodically. + See [the AccessList documentation](../../access-controls/access-lists.mdx) for + a high-level explanation of the feature, + and [the AccessList IaC guide](access-list.mdx) for a step by step IaC + AccessList setup. +- Allow users with the `engineer` role to request temporary access to + production, and have users with the `manager` role validate the requests. + See [the Access Requests documentation](../../access-controls/access-requests.mdx) +- You can see all supported fields in the references + of [the user resource](../../reference/resources.mdx#user) + and [the role resource](../../reference/resources.mdx#role). diff --git a/docs/pages/reference/introduction.mdx b/docs/pages/reference/introduction.mdx index f49f562abd5d1..dff6b80cb31e4 100644 --- a/docs/pages/reference/introduction.mdx +++ b/docs/pages/reference/introduction.mdx @@ -16,6 +16,7 @@ running Teleport. - [Helm Reference](./helm-reference.mdx): References for Teleport's Helm charts. - [Networking](./networking.mdx): Ports that Teleport services listen on, plus other information about how Teleport services communicate. +- [User types](./user-types.mdx): The different user representations in Teleport. - [Authentication](./authentication.mdx): Teleport's authentication connectors. - [Signals](./signals.mdx): The signals you can use to control a Teleport binary. diff --git a/docs/pages/reference/user-types.mdx b/docs/pages/reference/user-types.mdx new file mode 100644 index 0000000000000..a84520d9f2e3b --- /dev/null +++ b/docs/pages/reference/user-types.mdx @@ -0,0 +1,92 @@ +--- +title: User Types +description: Describes the different types of Teleport users and their properties. +keywords: [user,idp,sso] +tocDepth: 3 +--- + +This guide explains the different kinds of users in Teleport, how they are +created, and their properties. + +## Local users + +Local users are created in Teleport. They are not coming from an +external system like an identity provider. + +Local users can be created via the CLI (`tctl users add`), by applying a user +resource manifest (`tctl create -f user.yaml`) or via the web UI. Their roles +and traits can be modified directly in Teleport. + +Those users can connect to Teleport directly via username/password and/or +additional authentication factors such as WebAuthn physical tokens, passkeys, or +one-time passwords. + +Local user login can be disabled via `cluster_auth_preference` or `teleport.yaml`. +Disabling local authentication is required for [FIPS/FedRAMP compliance +](../access-controls/compliance-frameworks/fedramp.mdx). + +### Special case: Bots + +Machine ID provides machines with an identity that can authenticate to the +Teleport cluster. This identity is known as a bot. Bots are represented in +Teleport by a user and a role resource and can be created via the +`tctl bots add` command. + +Unlike human users, who use a password, MFA, or SSO, bot users join +the cluster as Teleport services using [a join method](./join-methods.mdx). They +can still join even if local auth is disabled. + +See the [Machine ID introduction](../machine-id/introduction.mdx) for more information. + +## SSO users + +Single Sign-On (SSO) users are imported in Teleport from an external identity provider. +Teleport contains a user resource representing those users, but it's only a +representation of a user of a remote system. + +Remote users don't perform their login challenge in Teleport. They are redirected +to their identity provider (IdP) to enter their password, MFA, or any +authentication method required by the upstream SSO provider. Teleport is not +aware of the authentication method not the user credentials, it trusts the IdP +response. + +If `teleport.auth_service.authentication.second_factor` is `webauthn`, Teleport +might ask for an additional MFA for administrative actions. This protects +against IdP compromise. + +SSO users cannot be edited via `tctl`, or via any other IaC tooling like +Terraform or the Teleport Kubernetes Operator. They are managed by Teleport. + +### Temporary users + +Users logging in via GitHub, SAML, or OIDC connectors are created in Teleport +after a successful login. At that time, their roles and traits are computed +according to the connector mappings. + +Those users are short-lived: they are created when a Teleport session is opened +and automatically expire. The expiry is dynamically computed based on the IdP +answer validity, the max session duration allowed by the user roles, and cannot +exceed 30 hours. Those users cannot be edited via `tctl`, only deleted. + +See the [SSO setup guides](../access-controls/sso.mdx) to learn how to setup an +authentication connector and allow user to log in via an IdP. + +### Synced users + +Since version 15, Teleport supports fetching users from external identity +providers like Okta. + +Synchronizing users from the external IdP allows all users to be represented in +Teleport, whether they logged in Teleport or not. The benefits of such +integration are: +- Automatic user locking and deletion if the user is suspended or removed in the + IdP. +- Ability to see all users within Teleport regardless of the last login date. +- All IdP users are displayed in Teleport Access Graph. + +The Okta synchronization service is in charge of creating new users when they +are created in Okta, and locking/deleting users if they get deactivated/removed +in Okta. + +Those users can be identified by the label `teleport.dev/origin: okta` and +cannot be edited via `tctl`, only deleted. diff --git a/examples/resources/terraform/provider-cloud.tf b/examples/resources/terraform/provider-cloud.tf new file mode 100644 index 0000000000000..dd5637478e90c --- /dev/null +++ b/examples/resources/terraform/provider-cloud.tf @@ -0,0 +1,30 @@ +terraform { + required_providers { + teleport = { + source = "terraform.releases.teleport.dev/gravitational/teleport" + version = "~> (=teleport.major_version=).0" + } + } +} + +provider "teleport" { + # Update addr to point to your Teleport Cloud tenant URL's host:port + addr = "mytenant.teleport.sh:443" + identity_file_path = "terraform-identity" +} + +# creates a test role, if we don't declare resources, Terraform won't try to +# connect to Teleport and we won't be able to validate the setup. +resource "teleport_role" "test" { + version = "v7" + metadata = { + name = "test" + description = "Dummy role to validate Terraform Provider setup" + labels = { + test = "yes" + } + } + + spec = { + } +} diff --git a/examples/resources/terraform/provider-self-hosted.tf b/examples/resources/terraform/provider-self-hosted.tf new file mode 100644 index 0000000000000..15bcf1a25862f --- /dev/null +++ b/examples/resources/terraform/provider-self-hosted.tf @@ -0,0 +1,31 @@ +terraform { + required_providers { + teleport = { + source = "terraform.releases.teleport.dev/gravitational/teleport" + version = "~> (=teleport.major_version=).0" + } + } +} + +provider "teleport" { + # Update addr to point to Teleport Auth/Proxy + # addr = "auth.example.com:3025" + addr = "proxy.example.com:443" + identity_file_path = "terraform-identity" +} + +# creates a test role, if we don't declare resources, Terraform won't try to +# connect to Teleport and we won't be able to validate the setup. +resource "teleport_role" "test" { + version = "v7" + metadata = { + name = "test" + description = "Dummy role to validate Terraform Provider setup" + labels = { + test = "yes" + } + } + + spec = { + } +} diff --git a/examples/resources/terraform/terraform-user-role-cloud.tf b/examples/resources/terraform/terraform-user-role-cloud.tf deleted file mode 100644 index da2c045fc0c67..0000000000000 --- a/examples/resources/terraform/terraform-user-role-cloud.tf +++ /dev/null @@ -1,85 +0,0 @@ -terraform { - required_providers { - teleport = { - source = "terraform.releases.teleport.dev/gravitational/teleport" - version = "~> (=teleport.major_version=).0" - } - } -} - -provider "teleport" { - # Update addr to point to your Teleport Cloud tenant URL's host:port - addr = "mytenant.teleport.sh:443" - identity_file_path = "terraform-identity" -} - -resource "teleport_role" "terraform-test" { - version = "v7" - metadata = { - name = "terraform-test" - description = "Terraform test role" - labels = { - example = "yes" - } - } - - spec = { - options = { - forward_agent = false - max_session_ttl = "30m" - port_forwarding = false - client_idle_timeout = "1h" - disconnect_expired_cert = true - permit_x11_forwarding = false - request_access = "denied" - } - - allow = { - logins = ["this-user-does-not-exist"] - - rules = [ - { - resources = ["user", "role"] - verbs = ["list"] - } - ] - - request = { - roles = ["example"] - claims_to_roles = [ - { - claim = "example" - value = "example" - roles = ["example"] - } - ] - } - - node_labels = { - key = ["example"] - alabel = ["with", "multiple", "values"] - } - } - - deny = { - logins = ["anonymous"] - } - } -} - -resource "teleport_user" "terraform-test" { - version = "v2" - metadata = { - name = "terraform-test" - description = "Test terraform user" - expires = "2022-10-12T07:20:50Z" - - labels = { - test = "true" - } - } - - spec = { - roles = ["terraform-test"] - } -} diff --git a/examples/resources/terraform/terraform-user-role-self-hosted.tf b/examples/resources/terraform/terraform-user-role-self-hosted.tf deleted file mode 100644 index 9ea26a644e7ee..0000000000000 --- a/examples/resources/terraform/terraform-user-role-self-hosted.tf +++ /dev/null @@ -1,86 +0,0 @@ -terraform { - required_providers { - teleport = { - source = "terraform.releases.teleport.dev/gravitational/teleport" - version = "~> (=teleport.major_version=).0" - } - } -} - -provider "teleport" { - # Update addr to point to Teleport Auth/Proxy - # addr = "auth.example.com:3025" - addr = "proxy.example.com:443" - identity_file_path = "terraform-identity" -} - -resource "teleport_role" "terraform-test" { - version = "v7" - metadata = { - name = "terraform-test" - description = "Terraform test role" - labels = { - example = "yes" - } - } - - spec = { - options = { - forward_agent = false - max_session_ttl = "30m" - port_forwarding = false - client_idle_timeout = "1h" - disconnect_expired_cert = true - permit_x11_forwarding = false - request_access = "denied" - } - - allow = { - logins = ["this-user-does-not-exist"] - - rules = [ - { - resources = ["user", "role"] - verbs = ["list"] - } - ] - - request = { - roles = ["example"] - claims_to_roles = [ - { - claim = "example" - value = "example" - roles = ["example"] - } - ] - } - - node_labels = { - key = ["example"] - alabel = ["with", "multiple", "values"] - } - } - - deny = { - logins = ["anonymous"] - } - } -} - -resource "teleport_user" "terraform-test" { - version = "v2" - metadata = { - name = "terraform-test" - description = "Test terraform user" - expires = "2022-10-12T07:20:50Z" - - labels = { - test = "true" - } - } - - spec = { - roles = ["terraform-test"] - } -}