diff --git a/docs/config.json b/docs/config.json
index 2b39965a1ea1f..d405d216200d0 100644
--- a/docs/config.json
+++ b/docs/config.json
@@ -28,7 +28,7 @@
},
{
"title": "Set up Single Sign-On",
- "slug": "/access-controls/sso/overview/"
+ "slug": "/admin-guides/authentication/sso/overview/"
},
{
"title": "Use Infrastructure as Code",
diff --git a/docs/pages/access-controls.mdx b/docs/pages/access-controls.mdx
deleted file mode 100644
index 80bec5bebd699..0000000000000
--- a/docs/pages/access-controls.mdx
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: Teleport Access Controls
-description: Configure Teleport to implement the principal of least privilege in your infrastructure.
----
-
-{/*TOPICS*/}
-
-- [Getting Started With Access Controls](access-controls/getting-started.mdx): Get started using Teleport Access Controls.
-- [Getting Started with Access Monitoring](access-controls/access-monitoring.mdx): Learn how to use Access Monitoring.
-- [Manage Access to your Cluster](access-controls/introduction.mdx): How to provide role-based access control (RBAC) for servers, databases, Kubernetes clusters, and other resources in your infrastructure
-- [Teleport Access Controls Reference](access-controls/reference.mdx): Explains the configuration settings that you can include in a Teleport role, which enables you to apply access controls for your infrastructure.
-
-## Access Lists
-
-Use Access Lists in Teleport ([more info](access-controls/access-lists.mdx))
-
-- [Access List Reference](access-controls/access-lists/reference.mdx): An explanation and overview of Access Lists in Teleport.
-- [Getting Started with Access Lists](access-controls/access-lists/guide.mdx): Learn how to use Access Lists to manage and audit long lived access to Teleport resources.
-
-## Cluster Access and RBAC
-
-How to configure access to specific resources in your infrastructure or your Teleport cluster as a whole. ([more info](access-controls/guides.mdx))
-
-- [Dual Authorization](access-controls/guides/dual-authz.mdx): Dual Authorization for SSH and Kubernetes.
-- [Hardware Key Support](access-controls/guides/hardware-key-support.mdx): Hardware Key Support
-- [Headless WebAuthn](access-controls/guides/headless.mdx): Headless WebAuthn
-- [IP Pinning ](access-controls/guides/ip-pinning.mdx): How to enable IP pinning for Teleport users
-- [Impersonating Teleport Users](access-controls/guides/impersonation.mdx): How to issue short-lived certs on behalf of Teleport users using impersonation.
-- [MFA for Administrative Actions](access-controls/guides/mfa-for-admin-actions.mdx): Require MFA checks to perform administrative actions.
-- [Moderated Sessions](access-controls/guides/moderated-sessions.mdx): Describes the purpose of moderated sessions and how to configure roles to support moderated sessions in a Teleport cluster.
-- [Passwordless](access-controls/guides/passwordless.mdx): Learn how to use passwordless authentication with Teleport.
-- [Per-session MFA](access-controls/guides/per-session-mfa.mdx): Require MFA checks to initiate sessions.
-- [Second Factor: WebAuthn](access-controls/guides/webauthn.mdx): Configuring WebAuthn support in Teleport clusters.
-- [Session and Identity Locking](access-controls/guides/locking.mdx): How to lock compromised users or agents
-- [Teleport Role Templates](access-controls/guides/role-templates.mdx): This guide explains templating in Teleport roles. Templates allow you to enable access to resources depending on the traits of a local or single sign-on user.
-
-## Compliance Frameworks
-
-How to use Teleport's access controls to streamline compliance without sacrificing productivity. ([more info](access-controls/compliance-frameworks.mdx))
-
-- [FedRAMP Compliance for Infrastructure Access](access-controls/compliance-frameworks/fedramp.mdx): How to configure SSH, Kubernetes, database, and web app access to be FedRAMP compliant, including support for FIPS 140-2.
-- [SOC 2 compliance for SSH, Kubernetes, and Databases](access-controls/compliance-frameworks/soc2.mdx): How to configure SOC 2-compliant access to SSH, Kubernetes, databases, desktops, and web apps
-
-## Configure Teleport as an identity provider
-
-How to set up Teleport's identity provider functionality ([more info](access-controls/idps.mdx))
-
-- [Access GCP Web Console and API with a federated authentication.](access-controls/idps/saml-gcp-workforce-identity-federation.mdx): Manage Google Cloud Platform (GCP) web console access with Teleport SAMl IdP.
-- [SAML IdP Attribute Mapping](access-controls/idps/saml-attribute-mapping.mdx): How to map user attributes to custom SAML response
-- [SAML Identity Provider Reference](access-controls/idps/saml-reference.mdx): Reference documentation for the SAML identity provider
-- [Use Teleport's SAML Provider to authenticate with Grafana](access-controls/idps/saml-grafana.mdx): Configure Grafana to use identities provided by Teleport.
-- [Using Teleport as a SAML identity provider](access-controls/idps/saml-guide.mdx): How to configure and use Teleport as a SAML identity provider.
-
-## Device Trust
-
-Device Trust allows Teleport admins to enforce the use of trusted devices. ([more info](access-controls/device-trust.mdx))
-
-- [Device Trust Overview](access-controls/device-trust/concepts.mdx): Teleport Device Trust Concepts
-- [Enforce Device Trust](access-controls/device-trust/enforcing-device-trust.mdx): Learn how to enforce trusted devices with Teleport
-- [Getting Started with Device Trust](access-controls/device-trust/guide.mdx): Get started with Teleport Device Trust
-- [Jamf Pro Integration](access-controls/device-trust/jamf-integration.mdx): Sync your Jamf Pro inventory into Teleport
-- [Manage Trusted Devices](access-controls/device-trust/device-management.mdx): Learn how to manage Trusted Devices
-
-## Just-in-Time Access Request Plugins
-
-Use Teleport's Access Request plugins to least-privilege access without sacrificing productivity. ([more info](access-controls/access-request-plugins.mdx))
-
-- [Access Requests with Microsoft Teams](access-controls/access-request-plugins/ssh-approval-msteams.mdx): How to set up Teleport's Microsoft Teams plugin for privilege elevation approvals.
-- [Access Requests with Opsgenie](access-controls/access-request-plugins/opsgenie.mdx): How to set up Teleport's Opsgenie plugin for privilege elevation approvals.
-- [Access Requests with ServiceNow](access-controls/access-request-plugins/servicenow.mdx): How to set up Teleport's ServiceNow plugin for privilege elevation approvals.
-- [Run the Discord Access Request Plugin](access-controls/access-request-plugins/ssh-approval-discord.mdx): How to set up Teleport's Discord plugin for privilege elevation approvals.
-- [Run the Jira Access Request Plugin](access-controls/access-request-plugins/ssh-approval-jira.mdx): How to set up the Teleport Jira plugin to notify users when another user requests elevated privileges.
-- [Run the Mattermost Access Request plugin](access-controls/access-request-plugins/ssh-approval-mattermost.mdx): How to set up Teleport's Mattermost plugin for privilege elevation approvals.
-- [Run the PagerDuty Access Request Plugin](access-controls/access-request-plugins/ssh-approval-pagerduty.mdx): How to set up Teleport's PagerDuty plugin for privilege elevation approvals.
-- [Run the Slack Access Request Plugin](access-controls/access-request-plugins/ssh-approval-slack.mdx): How to set up Teleport's Slack plugin for privilege elevation approvals.
-- [Teleport Access Requests with Email](access-controls/access-request-plugins/ssh-approval-email.mdx): How to set up the Teleport email plugin to notify users when another user requests elevated privileges.
-
-## Just-in-Time Access Requests
-
-Just-in-time Access Requests allow Teleport users to request access to a resource or role depending on need. ([more info](access-controls/access-requests.mdx))
-
-- [Configure Access Requests](access-controls/access-requests/access-request-configuration.mdx): Describes the options available for configuring just-in-time access to roles and resources in your Teleport cluster.
-- [Just-in-Time Access Requests](access-controls/access-requests/overview.mdx): Use just-in-time Access Requests to request elevated privileges.
-- [Resource Access Requests](access-controls/access-requests/resource-requests.mdx): Teleport allows users to request access to specific resources from the CLI or UI. Requests can be escalated via ChatOps or anywhere else via our flexible Authorization Workflow API.
-- [Role Access Requests](access-controls/access-requests/role-requests.mdx): Use Just-in-time Access Requests to request new roles with elevated privileges.
-- [Teleport Community Edition Role Access Requests](access-controls/access-requests/oss-role-requests.mdx): Teleport Community Edition allows users to request access to roles from the CLI.
-
-## Login Rules
-
-Transform User Traits with Login Rules ([more info](access-controls/login-rules.mdx))
-
-- [Deploy Login Rules using Kubernetes Operator](access-controls/login-rules/kubernetes.mdx): Use Teleport's Kubernetes Operator to deploy Login Rules to your cluster
-- [Deploy Login Rules via Terraform](access-controls/login-rules/terraform.mdx): Use Teleport's Terraform Provider to deploy Login Rules to your cluster
-- [Login Rules Reference](access-controls/login-rules/reference.mdx): Reference documentation for Login Rules
-- [Set Up Login Rules](access-controls/login-rules/guide.mdx): Set up Login Rules to transform user traits
-
-## Teleport Access Graph
-
-Includes guides for Teleport Access Graph, which allows you to visualize RBAC policies in your infrastructure. ([more info](access-controls/access-graph.mdx))
-
-- [Discover AWS Access Patterns with Teleport Policy](access-controls/access-graph/aws-sync.mdx): Describes how to import and visualize AWS accounts access patterns using Teleport Policy and Access Graph.
-- [Run Teleport Access Graph on Self-Hosted Clusters with Helm](access-controls/access-graph/self-hosted-helm.mdx): undefined
-- [Run Teleport Access Graph on Self-Hosted Clusters](access-controls/access-graph/self-hosted.mdx): Describes how to deploy Teleport Access Graph on self-hosted clusters.
-- [Teleport Policy](access-controls/access-graph/overview.mdx): A reference for Access Graph with Teleport Policy.
-
-## Teleport Single-Sign-On
-
-Learn how to configure your single sign-on provider to allow authentication to Teleport. ([more info](access-controls/sso.mdx))
-
-- [Authentication With GitLab as an SSO provider](access-controls/sso/gitlab.mdx): How to configure Teleport access using GitLab for SSO
-- [Authentication With Okta as an SSO Provider](access-controls/sso/okta.mdx): How to configure Teleport access using Okta for SSO
-- [OAuth2 and OIDC authentication](access-controls/sso/oidc.mdx): How to configure Teleport access with OAuth2 or OpenID connect (OIDC)
-- [SSO with Active Directory Federation Services](access-controls/sso/adfs.mdx): How to configure Teleport access with Active Directory Federation Services
-- [Set up Single Sign-On with GitHub](access-controls/sso/github-sso.mdx): Setting up GitHub SSO
-- [Teleport Authentication with Azure Active Directory (AD)](access-controls/sso/azuread.mdx): How to configure Teleport access with Azure Active Directory.
-- [Teleport Authentication with Google Workspace (G Suite)](access-controls/sso/google-workspace.mdx): How to configure Teleport access with Google Workspace (formerly known as G Suite)
-- [Teleport Authentication with OneLogin as an SSO Provider](access-controls/sso/one-login.mdx): How to configure Teleport access using OneLogin as an SSO provider
-- [Teleport Single Sign-On Overview](access-controls/sso/overview.mdx): How to set up single sign-on (SSO) for SSH using Teleport
diff --git a/docs/pages/access-controls/guides.mdx b/docs/pages/access-controls/guides.mdx
deleted file mode 100644
index 4148e6fc98aa9..0000000000000
--- a/docs/pages/access-controls/guides.mdx
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: Cluster Access and RBAC
-description: How to configure access to specific resources in your infrastructure or your Teleport cluster as a whole.
-layout: tocless-doc
----
-
-Teleport gives you fine-grained control over who can access resources in your
-infrastructure as well as how they can access those resources. Once you have
-deployed a Teleport cluster, configure access controls to achieve the right
-security policies for your organization.
-
-{/*TOPICS*/}
-
-- [Dual Authorization](guides/dual-authz.mdx): Dual Authorization for SSH and Kubernetes.
-- [Hardware Key Support](guides/hardware-key-support.mdx): Hardware Key Support
-- [Headless WebAuthn](guides/headless.mdx): Headless WebAuthn
-- [IP Pinning ](guides/ip-pinning.mdx): How to enable IP pinning for Teleport users
-- [Impersonating Teleport Users](guides/impersonation.mdx): How to issue short-lived certs on behalf of Teleport users using impersonation.
-- [MFA for Administrative Actions](guides/mfa-for-admin-actions.mdx): Require MFA checks to perform administrative actions.
-- [Moderated Sessions](guides/moderated-sessions.mdx): Describes the purpose of moderated sessions and how to configure roles to support moderated sessions in a Teleport cluster.
-- [Passwordless](guides/passwordless.mdx): Learn how to use passwordless authentication with Teleport.
-- [Per-session MFA](guides/per-session-mfa.mdx): Require MFA checks to initiate sessions.
-- [Second Factor: WebAuthn](guides/webauthn.mdx): Configuring WebAuthn support in Teleport clusters.
-- [Session and Identity Locking](guides/locking.mdx): How to lock compromised users or agents
-- [Teleport Role Templates](guides/role-templates.mdx): This guide explains templating in Teleport roles. Templates allow you to enable access to resources depending on the traits of a local or single sign-on user.
diff --git a/docs/pages/access-controls/introduction.mdx b/docs/pages/access-controls/introduction.mdx
deleted file mode 100644
index 3e1d53d274eab..0000000000000
--- a/docs/pages/access-controls/introduction.mdx
+++ /dev/null
@@ -1,78 +0,0 @@
----
-title: Manage Access to your Cluster
-description: How to provide role-based access control (RBAC) for servers, databases, Kubernetes clusters, and other resources in your infrastructure
-layout: tocless-doc
----
-
-After [deploying a Teleport cluster](../deploy-a-cluster/introduction.mdx), the
-next step is to manage the access that Teleport users have to resources in your
-infrastructure.
-
-Teleport's role-based access control (RBAC) enables you to set fine-grained
-policies for who can perform certain actions against specific resources. For
-example:
-
-- Analytics team members can SSH into a MongoDB read replica, but not the main
- database.
-- Interns can't access production databases.
-- SREs can access a production server only when using a [trusted hardware
- device](./device-trust/guide.mdx).
-- Members of a team can access the production Kubernetes cluster if approved by
- someone else from the same team.
-
-## Get started
-
-Configure Access Controls with our five-minute [Getting
-Started](./getting-started.mdx) guide.
-
-## Set up Teleport roles
-
-The heart of Teleport's RBAC system is the **role**, a configuration document
-that specifies access policies for resources in your Teleport cluster.
-Assigning a role to a Teleport user applies the policies listed in the role to
-the user.
-
-See the [Cluster Access and RBAC](./guides.mdx) section for instructions on
-setting up Teleport roles.
-
-## Integrate with your Single Sign-On provider
-
-While you can create Teleport users directly on the Auth Service, the more
-scalable approach is to integrate Teleport with a Single Sign-On identity
-provider (IdP), such as Okta or GitHub.
-
-When a user authenticates to your Teleport cluster via your IdP, Teleport
-automatically assigns roles to the user based on data provided by the IdP. This
-means that you can implement a fully fledged infrastructure RBAC system based on
-your existing Single Sign-On solution.
-
-Read our [Single Sign-On guide](./sso.mdx) to get started.
-
-## Enable Access Requests
-
-With Access Requests, your Teleport cluster can grant a user temporary access to
-resources in your infrastructure based on the approval of other users. You can
-set up your RBAC so all privileged access is short lived, and there are no
-longstanding admin roles for attackers to hijack.
-
-[Get started with Access Requests](./access-requests.mdx).
-
-You can integrate Teleport with your existing communication tool, e.g., Slack,
-PagerDuty, or Microsoft Teams, so Teleport users can easily create and approve
-Access Requests.
-
-[Get started with Access Request plugins](./access-request-plugins/index.mdx).
-
-## Achieve compliance
-
-Teleport's RBAC features make it easier to manage access to your infrastructure
-in order to satisfy compliance requirements. Learn how to use Teleport to
-achieve compliance with:
-
-- [FedRAMP](./compliance-frameworks/fedramp.mdx)
-- [SOC 2](./compliance-frameworks/soc2.mdx)
-
-## Find out more
-
-Find out more information on Teleport's RBAC features by reading the [Access
-Controls Reference](./reference.mdx).
diff --git a/docs/pages/admin-guides.mdx b/docs/pages/admin-guides.mdx
index 967e99a782a96..ad76239765ba2 100644
--- a/docs/pages/admin-guides.mdx
+++ b/docs/pages/admin-guides.mdx
@@ -5,11 +5,14 @@ description: "Step-by-step guides to performing common Teleport tasks"
{/*TOPICS*/}
+- [Getting Started with Access Monitoring](admin-guides/access-monitoring.mdx): Learn how to use Access Monitoring.
+
## Common Operations
Contains guides for performing common tasks on a Teleport cluster after the initial setup phase. ([more info](admin-guides/common-operations.mdx))
- [Backup and Restore](admin-guides/common-operations/backup-restore.mdx): How to back up and restore your Teleport cluster state.
+- [Configure Teleport as an identity provider (section)](admin-guides/common-operations/idps.mdx): How to set up Teleport's identity provider functionality
- [Exporting Teleport Audit Events (section)](admin-guides/common-operations/export-audit-events.mdx): Learn how to export Teleport audit events to your log management solution.
- [External Audit Storage](admin-guides/common-operations/external-audit-storage.mdx): Store audit logs and session recordings on your own infrastructure with Teleport Enterprise Cloud.
- [Run Teleport as a Daemon](admin-guides/common-operations/daemon.mdx): Configure Teleport to run as a daemon using systemd
@@ -52,7 +55,38 @@ Guides to deploying and managing the Teleport Auth Service and Proxy Service. ([
## Teleport Access Controls
-Guides to configuring the access that Teleport users have to infrastructure resources and cluster permissions. ([more info](admin-guides/rbac.mdx))
-
-- [Configure Trusted Clusters](admin-guides/rbac/trustedclusters.mdx): Explains how you can configure a trust relationship and manage access between two Teleport clusters.
-- [Teleport Label Guides (section)](admin-guides/rbac/labels.mdx): Guides to using Teleport labels, which underpin the Teleport role-based access controls system.
+Guides to configuring the access that Teleport users have to infrastructure resources and cluster permissions. ([more info](admin-guides/access-controls.mdx))
+
+- [Configure Trusted Clusters](admin-guides/access-controls/trustedclusters.mdx): Explains how you can configure a trust relationship and manage access between two Teleport clusters.
+- [Getting Started With Access Controls](admin-guides/access-controls/access-controls-getting-started.mdx): Get started using Teleport Access Controls.
+- [IP Pinning ](admin-guides/access-controls/ip-pinning.mdx): How to enable IP pinning for Teleport users
+- [Impersonating Teleport Users](admin-guides/access-controls/impersonation.mdx): How to issue short-lived certs on behalf of Teleport users using impersonation.
+- [Just-in-Time Access with Teleport (section)](admin-guides/access-controls/just-in-time.mdx): Provide elevated privileges for a limited period of time to allow users to access resources without the need for permanent admin roles.
+- [Login Rules (section)](admin-guides/access-controls/login-rules.mdx): Transform User Traits with Login Rules
+- [Moderated Sessions](admin-guides/access-controls/moderated-sessions.mdx): Describes the purpose of moderated sessions and how to configure roles to support moderated sessions in a Teleport cluster.
+- [Session and Identity Locking](admin-guides/access-controls/locking.mdx): How to lock compromised users or agents
+- [Teleport Label Guides (section)](admin-guides/access-controls/labels.mdx): Guides to using Teleport labels, which underpin the Teleport role-based access controls system.
+- [Teleport Role Templates](admin-guides/access-controls/role-templates.mdx): This guide explains templating in Teleport roles. Templates allow you to enable access to resources depending on the traits of a local or single sign-on user.
+
+## Teleport Access Graph
+
+Includes guides for Teleport Access Graph, which allows you to visualize RBAC policies in your infrastructure. ([more info](admin-guides/access-graph.mdx))
+
+- [Discover AWS Access Patterns with Teleport Policy](admin-guides/access-graph/aws-sync.mdx): Describes how to import and visualize AWS accounts access patterns using Teleport Policy and Access Graph.
+- [Run Teleport Access Graph on Self-Hosted Clusters with Helm](admin-guides/access-graph/self-hosted-helm.mdx): undefined
+- [Run Teleport Access Graph on Self-Hosted Clusters](admin-guides/access-graph/self-hosted.mdx): Describes how to deploy Teleport Access Graph on self-hosted clusters.
+- [Teleport Policy](admin-guides/access-graph/overview.mdx): A reference for Access Graph with Teleport Policy.
+
+## Teleport Authentication
+
+Guides for configuring the way users authenticate to Teleport. ([more info](admin-guides/authentication.mdx))
+
+- [Device Trust (section)](admin-guides/authentication/device-trust.mdx): Device Trust allows Teleport admins to enforce the use of trusted devices.
+- [Dual Authorization](admin-guides/authentication/dual-authz.mdx): Dual Authorization for SSH and Kubernetes.
+- [Hardware Key Support](admin-guides/authentication/hardware-key-support.mdx): Hardware Key Support
+- [Headless WebAuthn](admin-guides/authentication/headless.mdx): Headless WebAuthn
+- [MFA for Administrative Actions](admin-guides/authentication/mfa-for-admin-actions.mdx): Require MFA checks to perform administrative actions.
+- [Passwordless](admin-guides/authentication/passwordless.mdx): Learn how to use passwordless authentication with Teleport.
+- [Per-session MFA](admin-guides/authentication/per-session-mfa.mdx): Require MFA checks to initiate sessions.
+- [Second Factor: WebAuthn](admin-guides/authentication/webauthn.mdx): Configuring WebAuthn support in Teleport clusters.
+- [Teleport Single-Sign-On (section)](admin-guides/authentication/sso.mdx): Learn how to configure your single sign-on provider to allow authentication to Teleport.
diff --git a/docs/pages/admin-guides/access-controls.mdx b/docs/pages/admin-guides/access-controls.mdx
new file mode 100644
index 0000000000000..ecef8f72a3368
--- /dev/null
+++ b/docs/pages/admin-guides/access-controls.mdx
@@ -0,0 +1,38 @@
+---
+title: Teleport Access Controls
+description: Guides to configuring the access that Teleport users have to infrastructure resources and cluster permissions.
+---
+
+{/*TOPICS*/}
+
+- [Configure Trusted Clusters](access-controls/trustedclusters.mdx): Explains how you can configure a trust relationship and manage access between two Teleport clusters.
+- [Getting Started With Access Controls](access-controls/access-controls-getting-started.mdx): Get started using Teleport Access Controls.
+- [IP Pinning ](access-controls/ip-pinning.mdx): How to enable IP pinning for Teleport users
+- [Impersonating Teleport Users](access-controls/impersonation.mdx): How to issue short-lived certs on behalf of Teleport users using impersonation.
+- [Moderated Sessions](access-controls/moderated-sessions.mdx): Describes the purpose of moderated sessions and how to configure roles to support moderated sessions in a Teleport cluster.
+- [Session and Identity Locking](access-controls/locking.mdx): How to lock compromised users or agents
+- [Teleport Role Templates](access-controls/role-templates.mdx): This guide explains templating in Teleport roles. Templates allow you to enable access to resources depending on the traits of a local or single sign-on user.
+
+## Just-in-Time Access with Teleport
+
+Provide elevated privileges for a limited period of time to allow users to access resources without the need for permanent admin roles. ([more info](access-controls/just-in-time.mdx))
+
+- [Access Lists (section)](access-controls/just-in-time/access-lists.mdx): Use Access Lists in Teleport
+- [Just-in-Time Access Request Plugins (section)](access-controls/just-in-time/access-request-plugins.mdx): Use Teleport's Access Request plugins to least-privilege access without sacrificing productivity.
+- [Just-in-Time Access Requests (section)](access-controls/just-in-time/access-requests.mdx): Just-in-time Access Requests allow Teleport users to request access to a resource or role depending on need.
+
+## Login Rules
+
+Transform User Traits with Login Rules ([more info](access-controls/login-rules.mdx))
+
+- [Deploy Login Rules using Kubernetes Operator](access-controls/login-rules/kubernetes.mdx): Use Teleport's Kubernetes Operator to deploy Login Rules to your cluster
+- [Deploy Login Rules via Terraform](access-controls/login-rules/terraform.mdx): Use Teleport's Terraform Provider to deploy Login Rules to your cluster
+- [Set Up Login Rules](access-controls/login-rules/guide.mdx): Set up Login Rules to transform user traits
+
+## Teleport Label Guides
+
+Guides to using Teleport labels, which underpin the Teleport role-based access controls system. ([more info](access-controls/labels.mdx))
+
+- [Add Labels to Resources](access-controls/labels/labels.mdx): How to assign static and command-based dynamic labels to Teleport resources.
+- [EC2 Tags as Teleport Node Labels](access-controls/labels/ec2-tags.mdx): How to set up Teleport Node labels based on EC2 tags
+- [GCP Tags and Labels as Teleport Agent Labels](access-controls/labels/gcp-tags.mdx): How to set up Teleport agent labels based on GCP tags and labels
diff --git a/docs/pages/access-controls/getting-started.mdx b/docs/pages/admin-guides/access-controls/access-controls-getting-started.mdx
similarity index 100%
rename from docs/pages/access-controls/getting-started.mdx
rename to docs/pages/admin-guides/access-controls/access-controls-getting-started.mdx
diff --git a/docs/pages/access-controls/guides/impersonation.mdx b/docs/pages/admin-guides/access-controls/impersonation.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/impersonation.mdx
rename to docs/pages/admin-guides/access-controls/impersonation.mdx
diff --git a/docs/pages/access-controls/guides/ip-pinning.mdx b/docs/pages/admin-guides/access-controls/ip-pinning.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/ip-pinning.mdx
rename to docs/pages/admin-guides/access-controls/ip-pinning.mdx
diff --git a/docs/pages/admin-guides/access-controls/just-in-time.mdx b/docs/pages/admin-guides/access-controls/just-in-time.mdx
new file mode 100644
index 0000000000000..5ac42c6e1559f
--- /dev/null
+++ b/docs/pages/admin-guides/access-controls/just-in-time.mdx
@@ -0,0 +1,36 @@
+---
+title: Just-in-Time Access with Teleport
+description: Provide elevated privileges for a limited period of time to allow users to access resources without the need for permanent admin roles.
+---
+
+{/*TOPICS*/}
+
+## Access Lists
+
+Use Access Lists in Teleport ([more info](just-in-time/access-lists.mdx))
+
+- [Getting Started with Access Lists](just-in-time/access-lists/guide.mdx): Learn how to use Access Lists to manage and audit long lived access to Teleport resources.
+
+## Just-in-Time Access Request Plugins
+
+Use Teleport's Access Request plugins to least-privilege access without sacrificing productivity. ([more info](just-in-time/access-request-plugins.mdx))
+
+- [Access Requests with Microsoft Teams](just-in-time/access-request-plugins/ssh-approval-msteams.mdx): How to set up Teleport's Microsoft Teams plugin for privilege elevation approvals.
+- [Access Requests with Opsgenie](just-in-time/access-request-plugins/opsgenie.mdx): How to set up Teleport's Opsgenie plugin for privilege elevation approvals.
+- [Access Requests with ServiceNow](just-in-time/access-request-plugins/servicenow.mdx): How to set up Teleport's ServiceNow plugin for privilege elevation approvals.
+- [Routing Access Request notifications](just-in-time/access-request-plugins/notification-routing-rules.mdx): How to set up Teleport's Access Monitoring Rules to route Access Request notifications
+- [Run the Discord Access Request Plugin](just-in-time/access-request-plugins/ssh-approval-discord.mdx): How to set up Teleport's Discord plugin for privilege elevation approvals.
+- [Run the Jira Access Request Plugin](just-in-time/access-request-plugins/ssh-approval-jira.mdx): How to set up the Teleport Jira plugin to notify users when another user requests elevated privileges.
+- [Run the Mattermost Access Request plugin](just-in-time/access-request-plugins/ssh-approval-mattermost.mdx): How to set up Teleport's Mattermost plugin for privilege elevation approvals.
+- [Run the PagerDuty Access Request Plugin](just-in-time/access-request-plugins/ssh-approval-pagerduty.mdx): How to set up Teleport's PagerDuty plugin for privilege elevation approvals.
+- [Run the Slack Access Request Plugin](just-in-time/access-request-plugins/ssh-approval-slack.mdx): How to set up Teleport's Slack plugin for privilege elevation approvals.
+- [Teleport Access Requests with Email](just-in-time/access-request-plugins/ssh-approval-email.mdx): How to set up the Teleport email plugin to notify users when another user requests elevated privileges.
+
+## Just-in-Time Access Requests
+
+Just-in-time Access Requests allow Teleport users to request access to a resource or role depending on need. ([more info](just-in-time/access-requests.mdx))
+
+- [Just-in-Time Access Requests](just-in-time/access-requests/overview.mdx): Use just-in-time Access Requests to request elevated privileges.
+- [Resource Access Requests](just-in-time/access-requests/resource-requests.mdx): Teleport allows users to request access to specific resources from the CLI or UI. Requests can be escalated via ChatOps or anywhere else via our flexible Authorization Workflow API.
+- [Role Access Requests](just-in-time/access-requests/role-requests.mdx): Use Just-in-time Access Requests to request new roles with elevated privileges.
+- [Teleport Community Edition Role Access Requests](just-in-time/access-requests/oss-role-requests.mdx): Teleport Community Edition allows users to request access to roles from the CLI.
diff --git a/docs/pages/access-controls/access-lists.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-lists.mdx
similarity index 83%
rename from docs/pages/access-controls/access-lists.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-lists.mdx
index 202a8107100b8..8ddb4859e989e 100644
--- a/docs/pages/access-controls/access-lists.mdx
+++ b/docs/pages/admin-guides/access-controls/just-in-time/access-lists.mdx
@@ -11,5 +11,4 @@ traits, which then tie easily back into Teleport's existing RBAC system.
{/*TOPICS*/}
-- [Access List Reference](access-lists/reference.mdx): An explanation and overview of Access Lists in Teleport.
- [Getting Started with Access Lists](access-lists/guide.mdx): Learn how to use Access Lists to manage and audit long lived access to Teleport resources.
diff --git a/docs/pages/access-controls/access-lists/guide.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-lists/guide.mdx
similarity index 100%
rename from docs/pages/access-controls/access-lists/guide.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-lists/guide.mdx
diff --git a/docs/pages/access-controls/access-request-plugins.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins.mdx
similarity index 95%
rename from docs/pages/access-controls/access-request-plugins.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins.mdx
index fd075ef6c63ca..f859e0aa96a2e 100644
--- a/docs/pages/access-controls/access-request-plugins.mdx
+++ b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins.mdx
@@ -56,6 +56,7 @@ communication workflows by reading our setup guides:
- [Access Requests with Microsoft Teams](access-request-plugins/ssh-approval-msteams.mdx): How to set up Teleport's Microsoft Teams plugin for privilege elevation approvals.
- [Access Requests with Opsgenie](access-request-plugins/opsgenie.mdx): How to set up Teleport's Opsgenie plugin for privilege elevation approvals.
- [Access Requests with ServiceNow](access-request-plugins/servicenow.mdx): How to set up Teleport's ServiceNow plugin for privilege elevation approvals.
+- [Routing Access Request notifications](access-request-plugins/notification-routing-rules.mdx): How to set up Teleport's Access Monitoring Rules to route Access Request notifications
- [Run the Discord Access Request Plugin](access-request-plugins/ssh-approval-discord.mdx): How to set up Teleport's Discord plugin for privilege elevation approvals.
- [Run the Jira Access Request Plugin](access-request-plugins/ssh-approval-jira.mdx): How to set up the Teleport Jira plugin to notify users when another user requests elevated privileges.
- [Run the Mattermost Access Request plugin](access-request-plugins/ssh-approval-mattermost.mdx): How to set up Teleport's Mattermost plugin for privilege elevation approvals.
diff --git a/docs/pages/access-controls/access-request-plugins/notification-routing-rules.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/notification-routing-rules.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/notification-routing-rules.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/notification-routing-rules.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/opsgenie.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/opsgenie.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/opsgenie.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/opsgenie.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/servicenow.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/servicenow.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/servicenow.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/servicenow.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/ssh-approval-discord.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-discord.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/ssh-approval-discord.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-discord.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/ssh-approval-email.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-email.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/ssh-approval-email.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-email.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/ssh-approval-jira.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-jira.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/ssh-approval-jira.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-jira.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/ssh-approval-mattermost.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-mattermost.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/ssh-approval-mattermost.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-mattermost.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/ssh-approval-msteams.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-msteams.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/ssh-approval-msteams.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-msteams.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/ssh-approval-pagerduty.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-pagerduty.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/ssh-approval-pagerduty.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-pagerduty.mdx
diff --git a/docs/pages/access-controls/access-request-plugins/ssh-approval-slack.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-slack.mdx
similarity index 100%
rename from docs/pages/access-controls/access-request-plugins/ssh-approval-slack.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-request-plugins/ssh-approval-slack.mdx
diff --git a/docs/pages/access-controls/access-requests.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-requests.mdx
similarity index 84%
rename from docs/pages/access-controls/access-requests.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-requests.mdx
index 9da7d487d39d4..39d0386ec3b70 100644
--- a/docs/pages/access-controls/access-requests.mdx
+++ b/docs/pages/admin-guides/access-controls/just-in-time/access-requests.mdx
@@ -9,7 +9,6 @@ based on a configurable number of approvers.
{/*TOPICS*/}
-- [Configure Access Requests](access-requests/access-request-configuration.mdx): Describes the options available for configuring just-in-time access to roles and resources in your Teleport cluster.
- [Just-in-Time Access Requests](access-requests/overview.mdx): Use just-in-time Access Requests to request elevated privileges.
- [Resource Access Requests](access-requests/resource-requests.mdx): Teleport allows users to request access to specific resources from the CLI or UI. Requests can be escalated via ChatOps or anywhere else via our flexible Authorization Workflow API.
- [Role Access Requests](access-requests/role-requests.mdx): Use Just-in-time Access Requests to request new roles with elevated privileges.
diff --git a/docs/pages/access-controls/access-requests/oss-role-requests.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-requests/oss-role-requests.mdx
similarity index 100%
rename from docs/pages/access-controls/access-requests/oss-role-requests.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-requests/oss-role-requests.mdx
diff --git a/docs/pages/access-controls/access-requests/overview.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-requests/overview.mdx
similarity index 100%
rename from docs/pages/access-controls/access-requests/overview.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-requests/overview.mdx
diff --git a/docs/pages/access-controls/access-requests/resource-requests.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-requests/resource-requests.mdx
similarity index 100%
rename from docs/pages/access-controls/access-requests/resource-requests.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-requests/resource-requests.mdx
diff --git a/docs/pages/access-controls/access-requests/role-requests.mdx b/docs/pages/admin-guides/access-controls/just-in-time/access-requests/role-requests.mdx
similarity index 100%
rename from docs/pages/access-controls/access-requests/role-requests.mdx
rename to docs/pages/admin-guides/access-controls/just-in-time/access-requests/role-requests.mdx
diff --git a/docs/pages/admin-guides/rbac/labels.mdx b/docs/pages/admin-guides/access-controls/labels.mdx
similarity index 100%
rename from docs/pages/admin-guides/rbac/labels.mdx
rename to docs/pages/admin-guides/access-controls/labels.mdx
diff --git a/docs/pages/admin-guides/rbac/labels/ec2-tags.mdx b/docs/pages/admin-guides/access-controls/labels/ec2-tags.mdx
similarity index 100%
rename from docs/pages/admin-guides/rbac/labels/ec2-tags.mdx
rename to docs/pages/admin-guides/access-controls/labels/ec2-tags.mdx
diff --git a/docs/pages/admin-guides/rbac/labels/gcp-tags.mdx b/docs/pages/admin-guides/access-controls/labels/gcp-tags.mdx
similarity index 100%
rename from docs/pages/admin-guides/rbac/labels/gcp-tags.mdx
rename to docs/pages/admin-guides/access-controls/labels/gcp-tags.mdx
diff --git a/docs/pages/admin-guides/rbac/labels/labels.mdx b/docs/pages/admin-guides/access-controls/labels/labels.mdx
similarity index 100%
rename from docs/pages/admin-guides/rbac/labels/labels.mdx
rename to docs/pages/admin-guides/access-controls/labels/labels.mdx
diff --git a/docs/pages/access-controls/guides/locking.mdx b/docs/pages/admin-guides/access-controls/locking.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/locking.mdx
rename to docs/pages/admin-guides/access-controls/locking.mdx
diff --git a/docs/pages/access-controls/login-rules.mdx b/docs/pages/admin-guides/access-controls/login-rules.mdx
similarity index 83%
rename from docs/pages/access-controls/login-rules.mdx
rename to docs/pages/admin-guides/access-controls/login-rules.mdx
index 681beadf07ff7..a03ff8bbdf908 100644
--- a/docs/pages/access-controls/login-rules.mdx
+++ b/docs/pages/admin-guides/access-controls/login-rules.mdx
@@ -7,5 +7,4 @@ description: Transform User Traits with Login Rules
- [Deploy Login Rules using Kubernetes Operator](login-rules/kubernetes.mdx): Use Teleport's Kubernetes Operator to deploy Login Rules to your cluster
- [Deploy Login Rules via Terraform](login-rules/terraform.mdx): Use Teleport's Terraform Provider to deploy Login Rules to your cluster
-- [Login Rules Reference](login-rules/reference.mdx): Reference documentation for Login Rules
- [Set Up Login Rules](login-rules/guide.mdx): Set up Login Rules to transform user traits
diff --git a/docs/pages/access-controls/login-rules/guide.mdx b/docs/pages/admin-guides/access-controls/login-rules/guide.mdx
similarity index 100%
rename from docs/pages/access-controls/login-rules/guide.mdx
rename to docs/pages/admin-guides/access-controls/login-rules/guide.mdx
diff --git a/docs/pages/access-controls/login-rules/kubernetes.mdx b/docs/pages/admin-guides/access-controls/login-rules/kubernetes.mdx
similarity index 100%
rename from docs/pages/access-controls/login-rules/kubernetes.mdx
rename to docs/pages/admin-guides/access-controls/login-rules/kubernetes.mdx
diff --git a/docs/pages/access-controls/login-rules/terraform.mdx b/docs/pages/admin-guides/access-controls/login-rules/terraform.mdx
similarity index 100%
rename from docs/pages/access-controls/login-rules/terraform.mdx
rename to docs/pages/admin-guides/access-controls/login-rules/terraform.mdx
diff --git a/docs/pages/access-controls/guides/moderated-sessions.mdx b/docs/pages/admin-guides/access-controls/moderated-sessions.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/moderated-sessions.mdx
rename to docs/pages/admin-guides/access-controls/moderated-sessions.mdx
diff --git a/docs/pages/access-controls/guides/role-templates.mdx b/docs/pages/admin-guides/access-controls/role-templates.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/role-templates.mdx
rename to docs/pages/admin-guides/access-controls/role-templates.mdx
diff --git a/docs/pages/admin-guides/rbac/trustedclusters.mdx b/docs/pages/admin-guides/access-controls/trustedclusters.mdx
similarity index 100%
rename from docs/pages/admin-guides/rbac/trustedclusters.mdx
rename to docs/pages/admin-guides/access-controls/trustedclusters.mdx
diff --git a/docs/pages/access-controls/access-graph.mdx b/docs/pages/admin-guides/access-graph.mdx
similarity index 100%
rename from docs/pages/access-controls/access-graph.mdx
rename to docs/pages/admin-guides/access-graph.mdx
diff --git a/docs/pages/access-controls/access-graph/aws-sync.mdx b/docs/pages/admin-guides/access-graph/aws-sync.mdx
similarity index 100%
rename from docs/pages/access-controls/access-graph/aws-sync.mdx
rename to docs/pages/admin-guides/access-graph/aws-sync.mdx
diff --git a/docs/pages/access-controls/access-graph/overview.mdx b/docs/pages/admin-guides/access-graph/overview.mdx
similarity index 100%
rename from docs/pages/access-controls/access-graph/overview.mdx
rename to docs/pages/admin-guides/access-graph/overview.mdx
diff --git a/docs/pages/access-controls/access-graph/self-hosted-helm.mdx b/docs/pages/admin-guides/access-graph/self-hosted-helm.mdx
similarity index 100%
rename from docs/pages/access-controls/access-graph/self-hosted-helm.mdx
rename to docs/pages/admin-guides/access-graph/self-hosted-helm.mdx
diff --git a/docs/pages/access-controls/access-graph/self-hosted.mdx b/docs/pages/admin-guides/access-graph/self-hosted.mdx
similarity index 100%
rename from docs/pages/access-controls/access-graph/self-hosted.mdx
rename to docs/pages/admin-guides/access-graph/self-hosted.mdx
diff --git a/docs/pages/access-controls/access-monitoring.mdx b/docs/pages/admin-guides/access-monitoring.mdx
similarity index 100%
rename from docs/pages/access-controls/access-monitoring.mdx
rename to docs/pages/admin-guides/access-monitoring.mdx
diff --git a/docs/pages/admin-guides/authentication.mdx b/docs/pages/admin-guides/authentication.mdx
new file mode 100644
index 0000000000000..0a2c45f2fe0c7
--- /dev/null
+++ b/docs/pages/admin-guides/authentication.mdx
@@ -0,0 +1,38 @@
+---
+title: "Teleport Authentication"
+description: Guides for configuring the way users authenticate to Teleport.
+---
+
+{/*TOPICS*/}
+
+- [Dual Authorization](authentication/dual-authz.mdx): Dual Authorization for SSH and Kubernetes.
+- [Hardware Key Support](authentication/hardware-key-support.mdx): Hardware Key Support
+- [Headless WebAuthn](authentication/headless.mdx): Headless WebAuthn
+- [MFA for Administrative Actions](authentication/mfa-for-admin-actions.mdx): Require MFA checks to perform administrative actions.
+- [Passwordless](authentication/passwordless.mdx): Learn how to use passwordless authentication with Teleport.
+- [Per-session MFA](authentication/per-session-mfa.mdx): Require MFA checks to initiate sessions.
+- [Second Factor: WebAuthn](authentication/webauthn.mdx): Configuring WebAuthn support in Teleport clusters.
+
+## Device Trust
+
+Device Trust allows Teleport admins to enforce the use of trusted devices. ([more info](authentication/device-trust.mdx))
+
+- [Device Trust Overview](authentication/device-trust/concepts.mdx): Teleport Device Trust Concepts
+- [Enforce Device Trust](authentication/device-trust/enforcing-device-trust.mdx): Learn how to enforce trusted devices with Teleport
+- [Getting Started with Device Trust](authentication/device-trust/guide.mdx): Get started with Teleport Device Trust
+- [Jamf Pro Integration](authentication/device-trust/jamf-integration.mdx): Sync your Jamf Pro inventory into Teleport
+- [Manage Trusted Devices](authentication/device-trust/device-management.mdx): Learn how to manage Trusted Devices
+
+## Teleport Single-Sign-On
+
+Learn how to configure your single sign-on provider to allow authentication to Teleport. ([more info](authentication/sso.mdx))
+
+- [Authentication With GitLab as an SSO provider](authentication/sso/gitlab.mdx): How to configure Teleport access using GitLab for SSO
+- [Authentication With Okta as an SSO Provider](authentication/sso/okta.mdx): How to configure Teleport access using Okta for SSO
+- [OAuth2 and OIDC authentication](authentication/sso/oidc.mdx): How to configure Teleport access with OAuth2 or OpenID connect (OIDC)
+- [SSO with Active Directory Federation Services](authentication/sso/adfs.mdx): How to configure Teleport access with Active Directory Federation Services
+- [Set up Single Sign-On with GitHub](authentication/sso/github-sso.mdx): Setting up GitHub SSO
+- [Teleport Authentication with Azure Active Directory (AD)](authentication/sso/azuread.mdx): How to configure Teleport access with Azure Active Directory.
+- [Teleport Authentication with Google Workspace (G Suite)](authentication/sso/google-workspace.mdx): How to configure Teleport access with Google Workspace (formerly known as G Suite)
+- [Teleport Authentication with OneLogin as an SSO Provider](authentication/sso/one-login.mdx): How to configure Teleport access using OneLogin as an SSO provider
+- [Teleport Single Sign-On Overview](authentication/sso/overview.mdx): How to set up single sign-on (SSO) for SSH using Teleport
diff --git a/docs/pages/access-controls/device-trust.mdx b/docs/pages/admin-guides/authentication/device-trust.mdx
similarity index 100%
rename from docs/pages/access-controls/device-trust.mdx
rename to docs/pages/admin-guides/authentication/device-trust.mdx
diff --git a/docs/pages/access-controls/device-trust/concepts.mdx b/docs/pages/admin-guides/authentication/device-trust/concepts.mdx
similarity index 100%
rename from docs/pages/access-controls/device-trust/concepts.mdx
rename to docs/pages/admin-guides/authentication/device-trust/concepts.mdx
diff --git a/docs/pages/access-controls/device-trust/device-management.mdx b/docs/pages/admin-guides/authentication/device-trust/device-management.mdx
similarity index 100%
rename from docs/pages/access-controls/device-trust/device-management.mdx
rename to docs/pages/admin-guides/authentication/device-trust/device-management.mdx
diff --git a/docs/pages/access-controls/device-trust/enforcing-device-trust.mdx b/docs/pages/admin-guides/authentication/device-trust/enforcing-device-trust.mdx
similarity index 100%
rename from docs/pages/access-controls/device-trust/enforcing-device-trust.mdx
rename to docs/pages/admin-guides/authentication/device-trust/enforcing-device-trust.mdx
diff --git a/docs/pages/access-controls/device-trust/guide.mdx b/docs/pages/admin-guides/authentication/device-trust/guide.mdx
similarity index 100%
rename from docs/pages/access-controls/device-trust/guide.mdx
rename to docs/pages/admin-guides/authentication/device-trust/guide.mdx
diff --git a/docs/pages/access-controls/device-trust/jamf-integration.mdx b/docs/pages/admin-guides/authentication/device-trust/jamf-integration.mdx
similarity index 100%
rename from docs/pages/access-controls/device-trust/jamf-integration.mdx
rename to docs/pages/admin-guides/authentication/device-trust/jamf-integration.mdx
diff --git a/docs/pages/access-controls/guides/dual-authz.mdx b/docs/pages/admin-guides/authentication/dual-authz.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/dual-authz.mdx
rename to docs/pages/admin-guides/authentication/dual-authz.mdx
diff --git a/docs/pages/access-controls/guides/hardware-key-support.mdx b/docs/pages/admin-guides/authentication/hardware-key-support.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/hardware-key-support.mdx
rename to docs/pages/admin-guides/authentication/hardware-key-support.mdx
diff --git a/docs/pages/access-controls/guides/headless.mdx b/docs/pages/admin-guides/authentication/headless.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/headless.mdx
rename to docs/pages/admin-guides/authentication/headless.mdx
diff --git a/docs/pages/access-controls/guides/mfa-for-admin-actions.mdx b/docs/pages/admin-guides/authentication/mfa-for-admin-actions.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/mfa-for-admin-actions.mdx
rename to docs/pages/admin-guides/authentication/mfa-for-admin-actions.mdx
diff --git a/docs/pages/access-controls/guides/passwordless.mdx b/docs/pages/admin-guides/authentication/passwordless.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/passwordless.mdx
rename to docs/pages/admin-guides/authentication/passwordless.mdx
diff --git a/docs/pages/access-controls/guides/per-session-mfa.mdx b/docs/pages/admin-guides/authentication/per-session-mfa.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/per-session-mfa.mdx
rename to docs/pages/admin-guides/authentication/per-session-mfa.mdx
diff --git a/docs/pages/access-controls/sso.mdx b/docs/pages/admin-guides/authentication/sso.mdx
similarity index 100%
rename from docs/pages/access-controls/sso.mdx
rename to docs/pages/admin-guides/authentication/sso.mdx
diff --git a/docs/pages/access-controls/sso/adfs.mdx b/docs/pages/admin-guides/authentication/sso/adfs.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/adfs.mdx
rename to docs/pages/admin-guides/authentication/sso/adfs.mdx
diff --git a/docs/pages/access-controls/sso/azuread.mdx b/docs/pages/admin-guides/authentication/sso/azuread.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/azuread.mdx
rename to docs/pages/admin-guides/authentication/sso/azuread.mdx
diff --git a/docs/pages/access-controls/sso/github-sso.mdx b/docs/pages/admin-guides/authentication/sso/github-sso.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/github-sso.mdx
rename to docs/pages/admin-guides/authentication/sso/github-sso.mdx
diff --git a/docs/pages/access-controls/sso/gitlab.mdx b/docs/pages/admin-guides/authentication/sso/gitlab.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/gitlab.mdx
rename to docs/pages/admin-guides/authentication/sso/gitlab.mdx
diff --git a/docs/pages/access-controls/sso/google-workspace.mdx b/docs/pages/admin-guides/authentication/sso/google-workspace.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/google-workspace.mdx
rename to docs/pages/admin-guides/authentication/sso/google-workspace.mdx
diff --git a/docs/pages/access-controls/sso/oidc.mdx b/docs/pages/admin-guides/authentication/sso/oidc.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/oidc.mdx
rename to docs/pages/admin-guides/authentication/sso/oidc.mdx
diff --git a/docs/pages/access-controls/sso/okta.mdx b/docs/pages/admin-guides/authentication/sso/okta.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/okta.mdx
rename to docs/pages/admin-guides/authentication/sso/okta.mdx
diff --git a/docs/pages/access-controls/sso/one-login.mdx b/docs/pages/admin-guides/authentication/sso/one-login.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/one-login.mdx
rename to docs/pages/admin-guides/authentication/sso/one-login.mdx
diff --git a/docs/pages/access-controls/sso/overview.mdx b/docs/pages/admin-guides/authentication/sso/overview.mdx
similarity index 100%
rename from docs/pages/access-controls/sso/overview.mdx
rename to docs/pages/admin-guides/authentication/sso/overview.mdx
diff --git a/docs/pages/access-controls/guides/webauthn.mdx b/docs/pages/admin-guides/authentication/webauthn.mdx
similarity index 100%
rename from docs/pages/access-controls/guides/webauthn.mdx
rename to docs/pages/admin-guides/authentication/webauthn.mdx
diff --git a/docs/pages/admin-guides/common-operations.mdx b/docs/pages/admin-guides/common-operations.mdx
index 18fe018cb2c1e..9418afbf680d9 100644
--- a/docs/pages/admin-guides/common-operations.mdx
+++ b/docs/pages/admin-guides/common-operations.mdx
@@ -11,6 +11,16 @@ description: Contains guides for performing common tasks on a Teleport cluster a
- [Troubleshooting](common-operations/troubleshooting.mdx): Troubleshooting and Collecting Metrics of Teleport Processes
- [Uninstall Teleport](common-operations/uninstall-teleport.mdx): How to remove Teleport from your system
+## Configure Teleport as an identity provider
+
+How to set up Teleport's identity provider functionality ([more info](common-operations/idps.mdx))
+
+- [Access GCP Web Console and API with a federated authentication.](common-operations/idps/saml-gcp-workforce-identity-federation.mdx): Manage Google Cloud Platform (GCP) web console access with Teleport SAMl IdP.
+- [SAML IdP Attribute Mapping](common-operations/idps/saml-attribute-mapping.mdx): How to map user attributes to custom SAML response
+- [SAML Identity Provider Reference](common-operations/idps/saml-reference.mdx): Reference documentation for the SAML identity provider
+- [Use Teleport's SAML Provider to authenticate with Grafana](common-operations/idps/saml-grafana.mdx): Configure Grafana to use identities provided by Teleport.
+- [Using Teleport as a SAML identity provider](common-operations/idps/saml-guide.mdx): How to configure and use Teleport as a SAML identity provider.
+
## Exporting Teleport Audit Events
Learn how to export Teleport audit events to your log management solution. ([more info](common-operations/export-audit-events.mdx))
diff --git a/docs/pages/access-controls/idps.mdx b/docs/pages/admin-guides/common-operations/idps.mdx
similarity index 100%
rename from docs/pages/access-controls/idps.mdx
rename to docs/pages/admin-guides/common-operations/idps.mdx
diff --git a/docs/pages/access-controls/idps/saml-attribute-mapping.mdx b/docs/pages/admin-guides/common-operations/idps/saml-attribute-mapping.mdx
similarity index 100%
rename from docs/pages/access-controls/idps/saml-attribute-mapping.mdx
rename to docs/pages/admin-guides/common-operations/idps/saml-attribute-mapping.mdx
diff --git a/docs/pages/access-controls/idps/saml-gcp-workforce-identity-federation.mdx b/docs/pages/admin-guides/common-operations/idps/saml-gcp-workforce-identity-federation.mdx
similarity index 100%
rename from docs/pages/access-controls/idps/saml-gcp-workforce-identity-federation.mdx
rename to docs/pages/admin-guides/common-operations/idps/saml-gcp-workforce-identity-federation.mdx
diff --git a/docs/pages/access-controls/idps/saml-grafana.mdx b/docs/pages/admin-guides/common-operations/idps/saml-grafana.mdx
similarity index 100%
rename from docs/pages/access-controls/idps/saml-grafana.mdx
rename to docs/pages/admin-guides/common-operations/idps/saml-grafana.mdx
diff --git a/docs/pages/access-controls/idps/saml-guide.mdx b/docs/pages/admin-guides/common-operations/idps/saml-guide.mdx
similarity index 100%
rename from docs/pages/access-controls/idps/saml-guide.mdx
rename to docs/pages/admin-guides/common-operations/idps/saml-guide.mdx
diff --git a/docs/pages/access-controls/idps/saml-reference.mdx b/docs/pages/admin-guides/common-operations/idps/saml-reference.mdx
similarity index 100%
rename from docs/pages/access-controls/idps/saml-reference.mdx
rename to docs/pages/admin-guides/common-operations/idps/saml-reference.mdx
diff --git a/docs/pages/admin-guides/rbac.mdx b/docs/pages/admin-guides/rbac.mdx
deleted file mode 100644
index 32481fe182fdc..0000000000000
--- a/docs/pages/admin-guides/rbac.mdx
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: Teleport Access Controls
-description: Guides to configuring the access that Teleport users have to infrastructure resources and cluster permissions.
----
-
-{/*TOPICS*/}
-
-- [Configure Trusted Clusters](rbac/trustedclusters.mdx): Explains how you can configure a trust relationship and manage access between two Teleport clusters.
-
-## Teleport Label Guides
-
-Guides to using Teleport labels, which underpin the Teleport role-based access controls system. ([more info](rbac/labels.mdx))
-
-- [Add Labels to Resources](rbac/labels/labels.mdx): How to assign static and command-based dynamic labels to Teleport resources.
-- [EC2 Tags as Teleport Node Labels](rbac/labels/ec2-tags.mdx): How to set up Teleport Node labels based on EC2 tags
-- [GCP Tags and Labels as Teleport Agent Labels](rbac/labels/gcp-tags.mdx): How to set up Teleport agent labels based on GCP tags and labels
diff --git a/docs/pages/reference.mdx b/docs/pages/reference.mdx
index d86b3676ae83c..42d21c89eb382 100644
--- a/docs/pages/reference.mdx
+++ b/docs/pages/reference.mdx
@@ -32,6 +32,7 @@ Configuration and CLI reference for Teleport Machine ID. ([more info](reference/
References for concepts and tools available for operating Teleport. ([more info](reference/operations.mdx))
- [Authentication options](reference/operations/authentication.mdx): A reference for Teleport's authentication connectors
+- [Compliance Frameworks (section)](reference/operations/compliance-frameworks.mdx): How to use Teleport's access controls to streamline compliance without sacrificing productivity.
- [Join Methods and Token Reference](reference/operations/join-methods.mdx): Describes the different ways to configure a Teleport to join a cluster.
- [Local Users](reference/operations/users.mdx): Learn how to manage local users in Teleport. Local users are stored on the Auth Service instead of a third-party identity provider.
- [Networking](reference/operations/networking.mdx): This reference explains the networking requirements of a Teleport cluster, including its public address, ports, and support for HTTP CONNECT proxies.
@@ -39,6 +40,15 @@ References for concepts and tools available for operating Teleport. ([more info]
- [Teleport Signals Reference](reference/operations/signals.mdx): Signals you can send to a running teleport process.
- [User Types](reference/operations/user-types.mdx): Describes the different types of Teleport users and their properties.
+## Teleport Access Controls References
+
+Guides to configuring Teleport RBAC. ([more info](reference/rbac.mdx))
+
+- [Access List Reference](reference/rbac/access-lists.mdx): An explanation and overview of Access Lists in Teleport.
+- [Configure Access Requests](reference/rbac/access-request-configuration.mdx): Describes the options available for configuring just-in-time access to roles and resources in your Teleport cluster.
+- [Login Rules Reference](reference/rbac/login-rules.mdx): Reference documentation for Login Rules
+- [Teleport Access Controls Reference](reference/rbac/teleport-roles.mdx): Explains the configuration settings that you can include in a Teleport role, which enables you to apply access controls for your infrastructure.
+
## Teleport Agent Service References
Commands and configuration options for Teleport agent services, e.g., for protecting servers, databases, Kubernetes clusters, and Windows desktops. ([more info](reference/agents.mdx))
diff --git a/docs/pages/reference/operations.mdx b/docs/pages/reference/operations.mdx
index 684bca91541c7..e6a6126b398cb 100644
--- a/docs/pages/reference/operations.mdx
+++ b/docs/pages/reference/operations.mdx
@@ -15,3 +15,10 @@ Teleport.
- [Storage backends](operations/backends.mdx): How to configure Teleport deployment for high-availability using storage backends
- [Teleport Signals Reference](operations/signals.mdx): Signals you can send to a running teleport process.
- [User Types](operations/user-types.mdx): Describes the different types of Teleport users and their properties.
+
+## Compliance Frameworks
+
+How to use Teleport's access controls to streamline compliance without sacrificing productivity. ([more info](operations/compliance-frameworks.mdx))
+
+- [FedRAMP Compliance for Infrastructure Access](operations/compliance-frameworks/fedramp.mdx): How to configure SSH, Kubernetes, database, and web app access to be FedRAMP compliant, including support for FIPS 140-2.
+- [SOC 2 compliance for SSH, Kubernetes, and Databases](operations/compliance-frameworks/soc2.mdx): How to configure SOC 2-compliant access to SSH, Kubernetes, databases, desktops, and web apps
diff --git a/docs/pages/access-controls/compliance-frameworks.mdx b/docs/pages/reference/operations/compliance-frameworks.mdx
similarity index 100%
rename from docs/pages/access-controls/compliance-frameworks.mdx
rename to docs/pages/reference/operations/compliance-frameworks.mdx
diff --git a/docs/pages/access-controls/compliance-frameworks/fedramp.mdx b/docs/pages/reference/operations/compliance-frameworks/fedramp.mdx
similarity index 100%
rename from docs/pages/access-controls/compliance-frameworks/fedramp.mdx
rename to docs/pages/reference/operations/compliance-frameworks/fedramp.mdx
diff --git a/docs/pages/access-controls/compliance-frameworks/soc2.mdx b/docs/pages/reference/operations/compliance-frameworks/soc2.mdx
similarity index 100%
rename from docs/pages/access-controls/compliance-frameworks/soc2.mdx
rename to docs/pages/reference/operations/compliance-frameworks/soc2.mdx
diff --git a/docs/pages/reference/rbac.mdx b/docs/pages/reference/rbac.mdx
new file mode 100644
index 0000000000000..93d10ab787c41
--- /dev/null
+++ b/docs/pages/reference/rbac.mdx
@@ -0,0 +1,11 @@
+---
+title: Teleport Access Controls References
+description: Guides to configuring Teleport RBAC.
+---
+
+{/*TOPICS*/}
+
+- [Access List Reference](rbac/access-lists.mdx): An explanation and overview of Access Lists in Teleport.
+- [Configure Access Requests](rbac/access-request-configuration.mdx): Describes the options available for configuring just-in-time access to roles and resources in your Teleport cluster.
+- [Login Rules Reference](rbac/login-rules.mdx): Reference documentation for Login Rules
+- [Teleport Access Controls Reference](rbac/teleport-roles.mdx): Explains the configuration settings that you can include in a Teleport role, which enables you to apply access controls for your infrastructure.
diff --git a/docs/pages/access-controls/access-lists/reference.mdx b/docs/pages/reference/rbac/access-lists.mdx
similarity index 100%
rename from docs/pages/access-controls/access-lists/reference.mdx
rename to docs/pages/reference/rbac/access-lists.mdx
diff --git a/docs/pages/access-controls/access-requests/access-request-configuration.mdx b/docs/pages/reference/rbac/access-request-configuration.mdx
similarity index 100%
rename from docs/pages/access-controls/access-requests/access-request-configuration.mdx
rename to docs/pages/reference/rbac/access-request-configuration.mdx
diff --git a/docs/pages/access-controls/login-rules/reference.mdx b/docs/pages/reference/rbac/login-rules.mdx
similarity index 100%
rename from docs/pages/access-controls/login-rules/reference.mdx
rename to docs/pages/reference/rbac/login-rules.mdx
diff --git a/docs/pages/access-controls/reference.mdx b/docs/pages/reference/rbac/teleport-roles.mdx
similarity index 100%
rename from docs/pages/access-controls/reference.mdx
rename to docs/pages/reference/rbac/teleport-roles.mdx
diff --git a/integration/hostuser_test.go b/integration/hostuser_test.go
index 10041cb4a7631..076328c9e4441 100644
--- a/integration/hostuser_test.go
+++ b/integration/hostuser_test.go
@@ -28,6 +28,7 @@ import (
"os/exec"
"os/user"
"path/filepath"
+ "slices"
"testing"
"github.com/gravitational/trace"
@@ -180,7 +181,7 @@ func TestRootHostUsersBackend(t *testing.T) {
})
}
-func requireUserInGroups(t *testing.T, u *user.User, requiredGroups []string) {
+func getUserGroups(t *testing.T, u *user.User) []string {
var userGroups []string
userGids, err := u.GroupIds()
require.NoError(t, err)
@@ -189,7 +190,11 @@ func requireUserInGroups(t *testing.T, u *user.User, requiredGroups []string) {
require.NoError(t, err)
userGroups = append(userGroups, group.Name)
}
- require.Subset(t, userGroups, requiredGroups)
+ return userGroups
+}
+
+func requireUserInGroups(t *testing.T, u *user.User, requiredGroups []string) {
+ require.Subset(t, getUserGroups(t, u), requiredGroups)
}
func cleanupUsersAndGroups(users []string, groups []string) func() {
@@ -219,7 +224,7 @@ func TestRootHostUsers(t *testing.T) {
users := srv.NewHostUsers(context.Background(), presence, "host_uuid")
testGroups := []string{"group1", "group2"}
- closer, err := users.CreateUser(testuser, &services.HostUsersInfo{Groups: testGroups, Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP})
+ closer, err := users.UpsertUser(testuser, &services.HostUsersInfo{Groups: testGroups, Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP})
require.NoError(t, err)
testGroups = append(testGroups, types.TeleportServiceGroup)
@@ -244,7 +249,7 @@ func TestRootHostUsers(t *testing.T) {
_, err := user.LookupGroupId(testGID)
require.ErrorIs(t, err, user.UnknownGroupIdError(testGID))
- closer, err := users.CreateUser(testuser, &services.HostUsersInfo{
+ closer, err := users.UpsertUser(testuser, &services.HostUsersInfo{
Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP,
UID: testUID,
GID: testGID,
@@ -273,7 +278,7 @@ func TestRootHostUsers(t *testing.T) {
expectedHome := filepath.Join("/home", testuser)
require.NoDirExists(t, expectedHome)
- closer, err := users.CreateUser(testuser, &services.HostUsersInfo{Mode: types.CreateHostUserMode_HOST_USER_MODE_KEEP})
+ closer, err := users.UpsertUser(testuser, &services.HostUsersInfo{Mode: types.CreateHostUserMode_HOST_USER_MODE_KEEP})
require.NoError(t, err)
require.Nil(t, closer)
t.Cleanup(cleanupUsersAndGroups([]string{testuser}, nil))
@@ -303,7 +308,7 @@ func TestRootHostUsers(t *testing.T) {
os.Remove(sudoersPath(testuser, uuid))
host.UserDel(testuser)
})
- closer, err := users.CreateUser(testuser,
+ closer, err := users.UpsertUser(testuser,
&services.HostUsersInfo{
Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP,
})
@@ -334,12 +339,12 @@ func TestRootHostUsers(t *testing.T) {
deleteableUsers := []string{"teleport-user1", "teleport-user2", "teleport-user3"}
for _, user := range deleteableUsers {
- _, err := users.CreateUser(user, &services.HostUsersInfo{Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP})
+ _, err := users.UpsertUser(user, &services.HostUsersInfo{Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP})
require.NoError(t, err)
}
// this user should not be in the service group as it was created with mode keep.
- closer, err := users.CreateUser("teleport-user4", &services.HostUsersInfo{
+ closer, err := users.UpsertUser("teleport-user4", &services.HostUsersInfo{
Mode: types.CreateHostUserMode_HOST_USER_MODE_KEEP,
})
require.NoError(t, err)
@@ -360,4 +365,66 @@ func TestRootHostUsers(t *testing.T) {
require.Equal(t, err, user.UnknownUserError(us))
}
})
+
+ t.Run("test update changed groups", func(t *testing.T) {
+ tests := []struct {
+ name string
+ firstGroups []string
+ secondGroups []string
+ }{
+ {
+ name: "add groups",
+ secondGroups: []string{"group1", "group2"},
+ },
+ {
+ name: "delete groups",
+ firstGroups: []string{"group1", "group2"},
+ },
+ {
+ name: "change groups",
+ firstGroups: []string{"group1", "group2"},
+ secondGroups: []string{"group2", "group3"},
+ },
+ {
+ name: "no change",
+ firstGroups: []string{"group1", "group2"},
+ secondGroups: []string{"group2", "group1"},
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Cleanup(cleanupUsersAndGroups([]string{testuser}, slices.Concat(tc.firstGroups, tc.secondGroups)))
+
+ // Verify that the user is created with the first set of groups.
+ users := srv.NewHostUsers(context.Background(), presence, "host_uuid")
+ _, err := users.UpsertUser(testuser, &services.HostUsersInfo{
+ Groups: tc.firstGroups,
+ Mode: types.CreateHostUserMode_HOST_USER_MODE_KEEP,
+ })
+ require.NoError(t, err)
+ u, err := user.Lookup(testuser)
+ require.NoError(t, err)
+ requireUserInGroups(t, u, tc.firstGroups)
+
+ // Verify that the user is updated with the second set of groups.
+ _, err = users.UpsertUser(testuser, &services.HostUsersInfo{
+ Groups: tc.secondGroups,
+ Mode: types.CreateHostUserMode_HOST_USER_MODE_KEEP,
+ })
+ require.NoError(t, err)
+ u, err = user.Lookup(testuser)
+ require.NoError(t, err)
+ requireUserInGroups(t, u, tc.secondGroups)
+
+ // Verify that the appropriate groups form the first set were deleted.
+ userGroups := getUserGroups(t, u)
+ for _, group := range tc.firstGroups {
+ if !slices.Contains(tc.secondGroups, group) {
+ require.NotContains(t, userGroups, group)
+ }
+ }
+ })
+ }
+ })
}
diff --git a/lib/backend/dynamo/atomicwrite.go b/lib/backend/dynamo/atomicwrite.go
index d0a61cb1ee66c..78a506a1a5b13 100644
--- a/lib/backend/dynamo/atomicwrite.go
+++ b/lib/backend/dynamo/atomicwrite.go
@@ -199,6 +199,10 @@ TxnLoop:
if err != nil {
txnErr := &dynamodb.TransactionCanceledException{}
if !errors.As(err, &txnErr) {
+ if s := err.Error(); strings.Contains(s, "AccessDenied") && strings.Contains(s, "dynamodb:ConditionCheckItem") {
+ b.Warnf("AtomicWrite failed with error that may indicate dynamodb is missing the required dynamodb:ConditionCheckItem permission (this permission is now required for teleport v16 and later). Consider updating your IAM policy to include this permission. Original error: %v", err)
+ return "", trace.Errorf("teleport is missing required AWS permission dynamodb:ConditionCheckItem, please contact your administrator to update permissions")
+ }
return "", trace.Errorf("unexpected error during atomic write: %v", err)
}
diff --git a/lib/cloud/gcp/vm_test.go b/lib/cloud/gcp/vm_test.go
index 77cc248f84ba7..8bfbecd08d994 100644
--- a/lib/cloud/gcp/vm_test.go
+++ b/lib/cloud/gcp/vm_test.go
@@ -73,7 +73,8 @@ func TestConvertAPIError(t *testing.T) {
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
- require.True(t, trace.IsAccessDenied(convertAPIError(tc.err)))
+ err := convertAPIError(tc.err)
+ require.True(t, trace.IsAccessDenied(err), "unexpected error of type %T: %v", tc.err, err)
require.Contains(t, tc.err.Error(), "abcd1234")
})
}
diff --git a/lib/cloud/imds/gcp/imds.go b/lib/cloud/imds/gcp/imds.go
index 0830ab3938a9c..49525dc533794 100644
--- a/lib/cloud/imds/gcp/imds.go
+++ b/lib/cloud/imds/gcp/imds.go
@@ -76,12 +76,23 @@ func NewInstanceMetadataClient(ctx context.Context) (*InstanceMetadataClient, er
// IsAvailable checks if instance metadata is available.
func (client *InstanceMetadataClient) IsAvailable(ctx context.Context) bool {
- instanceData, err := client.getMetadata(ctx, "instance")
- return err == nil && instanceData != ""
+ _, err := client.getNumericID(ctx)
+ return err == nil
}
-// GetTags gets all of the GCP instance's labels (note: these are separate from
-// its tags, which we do not use).
+func (client *InstanceMetadataClient) getNumericID(ctx context.Context) (uint64, error) {
+ idStr, err := client.GetID(ctx)
+ if err != nil {
+ return 0, trace.Wrap(err)
+ }
+ id, err := strconv.ParseUint(idStr, 10, 64)
+ if err != nil || id == 0 {
+ return 0, trace.BadParameter("Invalid instance ID %q", idStr)
+ }
+ return id, nil
+}
+
+// GetTags gets all of the GCP instance's labels and tags.
func (client *InstanceMetadataClient) GetTags(ctx context.Context) (map[string]string, error) {
// Get a bunch of info from instance metadata.
projectID, err := client.GetProjectID(ctx)
@@ -96,11 +107,7 @@ func (client *InstanceMetadataClient) GetTags(ctx context.Context) (map[string]s
if err != nil {
return nil, trace.Wrap(err)
}
- idStr, err := client.GetID(ctx)
- if err != nil {
- return nil, trace.Wrap(err)
- }
- id, err := strconv.ParseUint(idStr, 10, 64)
+ id, err := client.getNumericID(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
diff --git a/lib/cloud/imds/gcp/imds_test.go b/lib/cloud/imds/gcp/imds_test.go
index 10ee2c1a2f5f6..ab33e44b4ddec 100644
--- a/lib/cloud/imds/gcp/imds_test.go
+++ b/lib/cloud/imds/gcp/imds_test.go
@@ -58,16 +58,51 @@ func (m *mockInstanceGetter) GetInstanceTags(ctx context.Context, req *gcp.Insta
func TestIsInstanceMetadataAvailable(t *testing.T) {
t.Parallel()
- t.Run("not available", func(t *testing.T) {
- client := &InstanceMetadataClient{
+ tests := []struct {
+ name string
+ getMetadata metadataGetter
+ assert require.BoolAssertionFunc
+ }{
+ {
+ name: "not available",
getMetadata: func(ctx context.Context, path string) (string, error) {
return "", trace.NotFound("")
},
- }
- require.False(t, client.IsAvailable(context.Background()))
- })
+ assert: require.False,
+ },
+ {
+ name: "not on gcp",
+ getMetadata: func(ctx context.Context, path string) (string, error) {
+ return "non-numeric id", nil
+ },
+ assert: require.False,
+ },
+ {
+ name: "zero ID",
+ getMetadata: func(ctx context.Context, path string) (string, error) {
+ return "0", nil
+ },
+ assert: require.False,
+ },
+ {
+ name: "on mocked gcp",
+ getMetadata: func(ctx context.Context, path string) (string, error) {
+ return "12345678", nil
+ },
+ assert: require.True,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ client := &InstanceMetadataClient{
+ getMetadata: tc.getMetadata,
+ }
+ tc.assert(t, client.IsAvailable(context.Background()))
+ })
+ }
- t.Run("on gcp", func(t *testing.T) {
+ t.Run("on real gcp", func(t *testing.T) {
if os.Getenv("TELEPORT_TEST_GCP") == "" {
t.Skip("not on gcp")
}
diff --git a/lib/service/service.go b/lib/service/service.go
index 6fc03b7c985b2..ec6278904b7ca 100644
--- a/lib/service/service.go
+++ b/lib/service/service.go
@@ -955,8 +955,14 @@ func NewTeleport(cfg *servicecfg.Config) (*TeleportProcess, error) {
imClient := cfg.InstanceMetadataClient
if imClient == nil {
imClient, err = cloud.DiscoverInstanceMetadata(supervisor.ExitContext())
- if err != nil && !trace.IsNotFound(err) {
- return nil, trace.Wrap(err)
+ if err == nil {
+ cfg.Logger.InfoContext(supervisor.ExitContext(),
+ "Found an instance metadata service. Teleport will import labels from this cloud instance.",
+ "type", imClient.GetType())
+ } else if !trace.IsNotFound(err) {
+ cfg.Logger.ErrorContext(supervisor.ExitContext(), "Error looking for cloud instance metadata", "error", err)
+ // Keep going. Not being able to fetch labels isn't necessarily an error (e.g. the user doesn't need imported
+ // labels and hasn't configured their cloud instance for it).
}
}
@@ -965,15 +971,16 @@ func NewTeleport(cfg *servicecfg.Config) (*TeleportProcess, error) {
if err == nil {
cloudHostname = strings.ReplaceAll(cloudHostname, " ", "_")
if utils.IsValidHostname(cloudHostname) {
- cfg.Logger.InfoContext(supervisor.ExitContext(), "Overriding hostname with value from cloud tag TeleportHostname.", "hostname", cloudHostname)
+ cfg.Logger.InfoContext(supervisor.ExitContext(), "Overriding hostname with value from cloud tag TeleportHostname", "hostname", cloudHostname)
cfg.Hostname = cloudHostname
// cloudHostname exists but is not a valid hostname.
} else if cloudHostname != "" {
- cfg.Logger.InfoContext(supervisor.ExitContext(), "Found invalid hostname in cloud tag TeleportHostname.", "hostname", cloudHostname)
+ cfg.Logger.InfoContext(supervisor.ExitContext(), "Found invalid hostname in cloud tag TeleportHostname", "hostname", cloudHostname)
}
} else if !trace.IsNotFound(err) {
- return nil, trace.Wrap(err)
+ cfg.Logger.ErrorContext(supervisor.ExitContext(), "Error looking for hostname tag", "error", err)
+ // Keep going.
}
cloudLabels, err = labels.NewCloudImporter(supervisor.ExitContext(), &labels.CloudConfig{
@@ -981,7 +988,8 @@ func NewTeleport(cfg *servicecfg.Config) (*TeleportProcess, error) {
Clock: cfg.Clock,
})
if err != nil {
- return nil, trace.Wrap(err)
+ cfg.Logger.ErrorContext(supervisor.ExitContext(), "Cloud labels will not be imported", "error", err)
+ // Keep going.
}
}
diff --git a/lib/service/service_test.go b/lib/service/service_test.go
index ec276e8bd1660..b42014e491124 100644
--- a/lib/service/service_test.go
+++ b/lib/service/service_test.go
@@ -1620,3 +1620,112 @@ func TestDebugServiceStartSocket(t *testing.T) {
defer req.Body.Close()
require.Equal(t, http.StatusNotFound, req.StatusCode)
}
+
+type mockInstanceMetadata struct {
+ hostname string
+ hostnameErr error
+}
+
+func (m *mockInstanceMetadata) IsAvailable(ctx context.Context) bool {
+ return true
+}
+
+func (m *mockInstanceMetadata) GetTags(ctx context.Context) (map[string]string, error) {
+ return nil, nil
+}
+
+func (m *mockInstanceMetadata) GetHostname(ctx context.Context) (string, error) {
+ return m.hostname, m.hostnameErr
+}
+
+func (m *mockInstanceMetadata) GetType() types.InstanceMetadataType {
+ return "mock"
+}
+
+func (m *mockInstanceMetadata) GetID(ctx context.Context) (string, error) {
+ return "", nil
+}
+
+func TestInstanceMetadata(t *testing.T) {
+ t.Parallel()
+
+ newCfg := func() *servicecfg.Config {
+ cfg := servicecfg.MakeDefaultConfig()
+ cfg.Hostname = "default.example.com"
+ cfg.SetAuthServerAddress(utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"})
+ cfg.Auth.ListenAddr = utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"}
+ cfg.Proxy.Enabled = false
+ cfg.SSH.Enabled = false
+ cfg.CircuitBreakerConfig = breaker.NoopBreakerConfig()
+ return cfg
+ }
+
+ tests := []struct {
+ name string
+ imClient imds.Client
+ expectCloudLabels bool
+ expectedHostname string
+ }{
+ {
+ name: "no instance metadata",
+ imClient: imds.NewDisabledIMDSClient(),
+ expectCloudLabels: false,
+ expectedHostname: "default.example.com",
+ },
+ {
+ name: "instance metadata with valid hostname",
+ imClient: &mockInstanceMetadata{
+ hostname: "new.example.com",
+ },
+ expectCloudLabels: true,
+ expectedHostname: "new.example.com",
+ },
+ {
+ name: "instance metadata with no hostname",
+ imClient: &mockInstanceMetadata{
+ hostnameErr: trace.NotFound(""),
+ },
+ expectCloudLabels: true,
+ expectedHostname: "default.example.com",
+ },
+ {
+ name: "instance metadata with invalid hostname",
+ imClient: &mockInstanceMetadata{
+ hostname: ")7%#(*&@())",
+ },
+ expectCloudLabels: true,
+ expectedHostname: "default.example.com",
+ },
+ {
+ name: "instance metadata with hostname error",
+ imClient: &mockInstanceMetadata{
+ hostnameErr: trace.Errorf(""),
+ },
+ expectCloudLabels: true,
+ expectedHostname: "default.example.com",
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ cfg := newCfg()
+ cfg.DataDir = t.TempDir()
+ cfg.Auth.StorageConfig.Params["path"] = t.TempDir()
+ cfg.InstanceMetadataClient = tc.imClient
+
+ process, err := NewTeleport(cfg)
+ require.NoError(t, err)
+ t.Cleanup(func() {
+ require.NoError(t, process.Close())
+ })
+
+ if tc.expectCloudLabels {
+ require.NotNil(t, process.cloudLabels)
+ } else {
+ require.Nil(t, process.cloudLabels)
+ }
+
+ require.Equal(t, tc.expectedHostname, cfg.Hostname)
+ })
+ }
+}
diff --git a/lib/srv/sess.go b/lib/srv/sess.go
index 461935b0455eb..1ba3e436fc801 100644
--- a/lib/srv/sess.go
+++ b/lib/srv/sess.go
@@ -281,7 +281,7 @@ func (s *SessionRegistry) TryCreateHostUser(ctx *ServerContext) error {
if trace.IsAccessDenied(err) && existsErr != nil {
return trace.WrapWithMessage(err, "Insufficient permission for host user creation")
}
- userCloser, err := s.users.CreateUser(ctx.Identity.Login, ui)
+ userCloser, err := s.users.UpsertUser(ctx.Identity.Login, ui)
if userCloser != nil {
ctx.AddCloser(userCloser)
}
diff --git a/lib/srv/usermgmt.go b/lib/srv/usermgmt.go
index af2ac11c812ea..d8ce41205908f 100644
--- a/lib/srv/usermgmt.go
+++ b/lib/srv/usermgmt.go
@@ -96,6 +96,8 @@ type HostUsersBackend interface {
LookupGroup(group string) (*user.Group, error)
// LookupGroupByID retrieves a group by its ID.
LookupGroupByID(gid string) (*user.Group, error)
+ // SetUserGroups sets a user's groups, replacing their existing groups.
+ SetUserGroups(name string, groups []string) error
// CreateGroup creates a group on a host.
CreateGroup(group string, gid string) error
// CreateUser creates a user on a host.
@@ -145,8 +147,8 @@ func (*HostSudoersNotImplemented) RemoveSudoers(name string) error {
}
type HostUsers interface {
- // CreateUser creates a temporary Teleport user in the TeleportServiceGroup
- CreateUser(name string, hostRoleInfo *services.HostUsersInfo) (io.Closer, error)
+ // UpsertUser creates a temporary Teleport user in the TeleportServiceGroup
+ UpsertUser(name string, hostRoleInfo *services.HostUsersInfo) (io.Closer, error)
// DeleteUser deletes a temporary Teleport user only if they are
// in a specified group
DeleteUser(name string, gid string) error
@@ -221,29 +223,71 @@ func (u *HostSudoersManagement) RemoveSudoers(name string) error {
return nil
}
-// CreateUser creates a temporary Teleport user in the TeleportServiceGroup
-func (u *HostUserManagement) CreateUser(name string, ui *services.HostUsersInfo) (io.Closer, error) {
+// UpsertUser creates a temporary Teleport user in the TeleportServiceGroup
+func (u *HostUserManagement) UpsertUser(name string, ui *services.HostUsersInfo) (io.Closer, error) {
if ui.Mode == types.CreateHostUserMode_HOST_USER_MODE_UNSPECIFIED {
return nil, trace.BadParameter("Mode is a required argument to CreateUser")
}
+ groups := make([]string, 0, len(ui.Groups))
+ for _, group := range ui.Groups {
+ if group == name {
+ // this causes an error as useradd expects the group with the same name as the user to be available
+ log.Debugf("Skipping group creation with name the same as login user (%q, %q).", name, group)
+ continue
+ }
+ groups = append(groups, group)
+ }
+ if ui.Mode == types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP {
+ groups = append(groups, types.TeleportServiceGroup)
+ }
+ var errs []error
+ for _, group := range groups {
+ if err := u.createGroupIfNotExist(group); err != nil {
+ errs = append(errs, err)
+ continue
+ }
+ }
+ if err := trace.NewAggregate(errs...); err != nil {
+ return nil, trace.WrapWithMessage(err, "error while creating groups")
+ }
+
tempUser, err := u.backend.Lookup(name)
if err != nil && !errors.Is(err, user.UnknownUserError(name)) {
return nil, trace.Wrap(err)
}
if tempUser != nil {
- gids, err := u.backend.UserGIDs(tempUser)
- if err != nil {
- return nil, trace.Wrap(err)
+ // Collect actions that need to be done together under a lock on the user.
+ actionsUnderLock := []func() error{
+ func() error {
+ // If the user exists, set user groups again as they might have changed.
+ return trace.Wrap(u.backend.SetUserGroups(name, groups))
+ },
+ }
+ doWithUserLock := func() error {
+ return trace.Wrap(u.doWithUserLock(func(_ types.SemaphoreLease) error {
+ for _, action := range actionsUnderLock {
+ if err := action(); err != nil {
+ return trace.Wrap(err)
+ }
+ }
+ return nil
+ }))
}
+
systemGroup, err := u.backend.LookupGroup(types.TeleportServiceGroup)
if err != nil {
if isUnknownGroupError(err, types.TeleportServiceGroup) {
- return nil, trace.AlreadyExists("User %q already exists, however no users are currently managed by teleport", name)
+ // Teleport service group doesn't exist, so we don't need to update interaction time.
+ return nil, trace.Wrap(doWithUserLock())
}
return nil, trace.Wrap(err)
}
+ gids, err := u.backend.UserGIDs(tempUser)
+ if err != nil {
+ return nil, trace.Wrap(err)
+ }
var found bool
for _, gid := range gids {
if gid == systemGroup.Gid {
@@ -252,16 +296,14 @@ func (u *HostUserManagement) CreateUser(name string, ui *services.HostUsersInfo)
}
}
if !found {
- return nil, trace.AlreadyExists("User %q already exists and is not managed by teleport", name)
+ // User isn't managed by Teleport, so we don't need to update interaction time.
+ return nil, trace.Wrap(doWithUserLock())
}
- err = u.doWithUserLock(func(_ types.SemaphoreLease) error {
- if err := u.storage.UpsertHostUserInteractionTime(u.ctx, name, time.Now()); err != nil {
- return trace.Wrap(err)
- }
- return nil
+ actionsUnderLock = append(actionsUnderLock, func() error {
+ return trace.Wrap(u.storage.UpsertHostUserInteractionTime(u.ctx, name, time.Now()))
})
- if err != nil {
+ if err := doWithUserLock(); err != nil {
return nil, trace.Wrap(err)
}
// try to delete even if the user already exists as only users
@@ -272,30 +314,7 @@ func (u *HostUserManagement) CreateUser(name string, ui *services.HostUsersInfo)
username: name,
users: u,
backend: u.backend,
- }, trace.AlreadyExists("User %q already exists", name)
- }
-
- groups := make([]string, 0, len(ui.Groups))
- for _, group := range ui.Groups {
- if group == name {
- // this causes an error as useradd expects the group with the same name as the user to be available
- log.Debugf("Skipping group creation with name the same as login user (%q, %q).", name, group)
- continue
- }
- groups = append(groups, group)
- }
- if ui.Mode == types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP {
- groups = append(groups, types.TeleportServiceGroup)
- }
- var errs []error
- for _, group := range groups {
- if err := u.createGroupIfNotExist(group); err != nil {
- errs = append(errs, err)
- continue
- }
- }
- if err := trace.NewAggregate(errs...); err != nil {
- return nil, trace.WrapWithMessage(err, "error while creating groups")
+ }, nil
}
var home string
@@ -307,8 +326,10 @@ func (u *HostUserManagement) CreateUser(name string, ui *services.HostUsersInfo)
}
err = u.doWithUserLock(func(_ types.SemaphoreLease) error {
- if err := u.storage.UpsertHostUserInteractionTime(u.ctx, name, time.Now()); err != nil {
- return trace.Wrap(err)
+ if ui.Mode != types.CreateHostUserMode_HOST_USER_MODE_KEEP {
+ if err := u.storage.UpsertHostUserInteractionTime(u.ctx, name, time.Now()); err != nil {
+ return trace.Wrap(err)
+ }
}
if ui.GID != "" {
// if gid is specified a group must already exist
@@ -341,7 +362,7 @@ func (u *HostUserManagement) CreateUser(name string, ui *services.HostUsersInfo)
}
if ui.Mode == types.CreateHostUserMode_HOST_USER_MODE_KEEP {
- return nil, trace.Wrap(err)
+ return nil, nil
}
closer := &userCloser{
diff --git a/lib/srv/usermgmt_linux.go b/lib/srv/usermgmt_linux.go
index 3a2e8acb6a01b..6dcf085743233 100644
--- a/lib/srv/usermgmt_linux.go
+++ b/lib/srv/usermgmt_linux.go
@@ -90,6 +90,12 @@ func (*HostUsersProvisioningBackend) LookupGroupByID(gid string) (*user.Group, e
return user.LookupGroupId(gid)
}
+// SetUserGroups sets a user's groups, replacing their existing groups.
+func (*HostUsersProvisioningBackend) SetUserGroups(name string, groups []string) error {
+ _, err := host.SetUserGroups(name, groups)
+ return trace.Wrap(err)
+}
+
// GetAllUsers returns a full list of users present on a system
func (*HostUsersProvisioningBackend) GetAllUsers() ([]string, error) {
users, _, err := host.GetAllUsers()
diff --git a/lib/srv/usermgmt_test.go b/lib/srv/usermgmt_test.go
index cd54df30f17f9..7003237105e2a 100644
--- a/lib/srv/usermgmt_test.go
+++ b/lib/srv/usermgmt_test.go
@@ -89,6 +89,14 @@ func (tm *testHostUserBackend) LookupGroupByID(gid string) (*user.Group, error)
}, nil
}
+func (tm *testHostUserBackend) SetUserGroups(name string, groups []string) error {
+ if _, ok := tm.users[name]; !ok {
+ return trace.NotFound("User %q doesn't exist", name)
+ }
+ tm.users[name] = groups
+ return nil
+}
+
func (tm *testHostUserBackend) UserGIDs(u *user.User) ([]string, error) {
ids := make([]string, 0, len(tm.users[u.Username]))
for _, id := range tm.users[u.Username] {
@@ -175,7 +183,7 @@ func TestUserMgmt_CreateTemporaryUser(t *testing.T) {
Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP,
}
// create a user with some groups
- closer, err := users.CreateUser("bob", userinfo)
+ closer, err := users.UpsertUser("bob", userinfo)
require.NoError(t, err)
require.NotNil(t, closer, "user closer was nil")
@@ -185,8 +193,8 @@ func TestUserMgmt_CreateTemporaryUser(t *testing.T) {
}, backend.users["bob"])
// try creat the same user again
- secondCloser, err := users.CreateUser("bob", userinfo)
- require.True(t, trace.IsAlreadyExists(err))
+ secondCloser, err := users.UpsertUser("bob", userinfo)
+ require.NoError(t, err)
require.NotNil(t, secondCloser)
// Close will remove the user if the user is in the teleport-system group
@@ -197,8 +205,8 @@ func TestUserMgmt_CreateTemporaryUser(t *testing.T) {
backend.CreateUser("simon", []string{}, "", "", "")
// try to create a temporary user for simon
- closer, err = users.CreateUser("simon", userinfo)
- require.True(t, trace.IsAlreadyExists(err))
+ closer, err = users.UpsertUser("simon", userinfo)
+ require.NoError(t, err)
require.Nil(t, closer)
}
@@ -217,7 +225,7 @@ func TestUserMgmtSudoers_CreateTemporaryUser(t *testing.T) {
backend: backend,
}
- closer, err := users.CreateUser("bob", &services.HostUsersInfo{
+ closer, err := users.UpsertUser("bob", &services.HostUsersInfo{
Groups: []string{"hello", "sudo"},
Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP,
})
@@ -241,16 +249,15 @@ func TestUserMgmtSudoers_CreateTemporaryUser(t *testing.T) {
// test user already exists but teleport-service group has not yet
// been created
backend.CreateUser("testuser", nil, "", "", "")
- _, err := users.CreateUser("testuser", &services.HostUsersInfo{
+ _, err := users.UpsertUser("testuser", &services.HostUsersInfo{
Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP,
})
- require.True(t, trace.IsAlreadyExists(err))
+ require.NoError(t, err)
backend.CreateGroup(types.TeleportServiceGroup, "")
- // IsAlreadyExists error when teleport-service group now exists
- _, err = users.CreateUser("testuser", &services.HostUsersInfo{
+ _, err = users.UpsertUser("testuser", &services.HostUsersInfo{
Mode: types.CreateHostUserMode_HOST_USER_MODE_INSECURE_DROP,
})
- require.True(t, trace.IsAlreadyExists(err))
+ require.NoError(t, err)
})
}
@@ -286,7 +293,7 @@ func TestUserMgmt_DeleteAllTeleportSystemUsers(t *testing.T) {
mgmt.CreateGroup(group, "")
}
if slices.Contains(user.groups, types.TeleportServiceGroup) {
- users.CreateUser(user.user, &services.HostUsersInfo{Groups: user.groups})
+ users.UpsertUser(user.user, &services.HostUsersInfo{Groups: user.groups})
} else {
mgmt.CreateUser(user.user, user.groups, "", "", "")
}
diff --git a/lib/utils/host/hostusers.go b/lib/utils/host/hostusers.go
index f6bacf0028636..92b2bd15e90b9 100644
--- a/lib/utils/host/hostusers.go
+++ b/lib/utils/host/hostusers.go
@@ -92,17 +92,15 @@ func UserAdd(username string, groups []string, home, uid, gid string) (exitCode
return cmd.ProcessState.ExitCode(), trace.Wrap(err)
}
-// AddUserToGroups adds a user to a list of specified groups on a host using `usermod`
-func AddUserToGroups(username string, groups []string) (exitCode int, err error) {
+// SetUserGroups adds a user to a list of specified groups on a host using `usermod`,
+// overriding any existing supplementary groups.
+func SetUserGroups(username string, groups []string) (exitCode int, err error) {
usermodBin, err := exec.LookPath("usermod")
if err != nil {
return -1, trace.Wrap(err, "cant find usermod binary")
}
- args := []string{"-aG"}
- args = append(args, groups...)
- args = append(args, username)
- // usermod -aG (append groups) (username)
- cmd := exec.Command(usermodBin, args...)
+ // usermod -G (replace groups) (username)
+ cmd := exec.Command(usermodBin, "-G", strings.Join(groups, ","), username)
output, err := cmd.CombinedOutput()
log.Debugf("%s output: %s", cmd.Path, string(output))
return cmd.ProcessState.ExitCode(), trace.Wrap(err)
diff --git a/package.json b/package.json
index 1f9b9a4204483..5bd1a0557d9f5 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "teleport-ui",
"version": "1.0.0",
"scripts": {
- "all-topics": "node docs/gen-topic-pages/index.js --in docs/pages/admin-guides,docs/pages/access-controls,docs/pages/connect-your-client,docs/pages/reference",
+ "all-topics": "node docs/gen-topic-pages/index.js --in docs/pages/admin-guides,docs/pages/connect-your-client,docs/pages/reference",
"build-ui": "yarn build-ui-oss && yarn build-ui-e",
"build-ui-oss": "yarn workspace @gravitational/teleport build",
"build-ui-e": "yarn workspace @gravitational/teleport.e build",
diff --git a/web/packages/shared/components/AccessRequests/AccessDuration/AccessDurationRequest.tsx b/web/packages/shared/components/AccessRequests/AccessDuration/AccessDurationRequest.tsx
index ed17b5b5b7b1c..1a141d7050491 100644
--- a/web/packages/shared/components/AccessRequests/AccessDuration/AccessDurationRequest.tsx
+++ b/web/packages/shared/components/AccessRequests/AccessDuration/AccessDurationRequest.tsx
@@ -16,70 +16,21 @@
* along with this program. If not, see .
*/
-import { useState, useEffect } from 'react';
+import React from 'react';
import { Flex, LabelInput, Text } from 'design';
import Select, { Option } from 'shared/components/Select';
import { ToolTipInfo } from 'shared/components/ToolTip';
-import { AccessRequest } from 'shared/services/accessRequests';
-
-import {
- getDurationOptionIndexClosestToOneWeek,
- getDurationOptionsFromStartTime,
-} from './durationOptions';
-
export function AccessDurationRequest({
- assumeStartTime,
- accessRequest,
maxDuration,
- setMaxDuration,
+ onMaxDurationChange,
+ maxDurationOptions,
}: {
- assumeStartTime: Date;
- accessRequest: AccessRequest;
+ maxDurationOptions: Option[];
maxDuration: Option;
- setMaxDuration(s: Option): void;
+ onMaxDurationChange(s: Option): void;
}) {
- // Options for extending or shortening the access request duration.
- const [durationOptions, setDurationOptions] = useState