Fork me on GitHub
Teleport

Teleport Kubernetes Access Controls

Improve

Single Sign-On and Kubernetes RBAC

Teleport issues short-lived X.509 certs and updates Kubernetes clients to talk to Teleport proxy using mutual TLS. It then intercepts every request and adds impersonation headers to map users to Kubernetes users and groups.

Impersonation

Teleport's connectors configure single sign-on for OIDC, OAuth, or SAML providers. Here are examples of connectors that map SSO users to Kubernetes groups in the Teleport Open Source Edition and Teleport's roles in the Enterprise Edition:

Github's teams_to_logins section maps users to roles based on users' teams.

kind: github
version: v3
metadata:
  # Connector name that will be used with `tsh --auth=github login`
  name: github
spec:
  # Client ID of Github OAuth app
  client_id: client-id
  # Client secret of Github OAuth app
  client_secret: client-secret
  # This name will be shown on UI login screen
  display: Github
  # Change tele.example.com to your domain name
  redirect_url: https://tele.example.com:443/v1/webapi/github/callback
  # Map github teams to teleport roles
  teams_to_logins:
    - organization: octocats # Github organization name
      team: admin            # Github team name within that organization
      # keep this field as is for now
      logins: ["admin"]

OIDC and SAML connectors claims_to_roles and attributes_to_roles sections map attribute statements and claims received from identity providers to Teleport's roles.

kind: saml
version: v2
metadata:
  name: okta
spec:
  acs: https://tele.example.com/v1/webapi/saml/acs
  attributes_to_roles:
  # Any user who has SAML `groups` atrribute with value `okta-admin`
  # will be given the Teleport `kube-access` role.
  - {name: "groups", value: "okta-admin", roles: ["kube-access"]}
  entity_descriptor: |
    <?xml !!! Make sure to shift all lines in XML descriptor
    with 4 spaces, otherwise things will not work

In this example, the kube-access role uses the kubernetes_groups property to assign Teleport users to Kubernetes groups

kind: role
version: v3
metadata:
  name: kube-access
spec:
  allow:
    # If kubernetes integration is enabled, this setting configures which
    # kubernetes groups the users of this role will be assigned to.
    # Note that you can refer to a SAML/OIDC trait named 'property' via the "{{external.property}}" template variable,
    # this allows you to specify Kubernetes group membership via your identity provider:
    kubernetes_groups: ["system:masters"]

Mapping OIDC claims and SAML attributes to Kubernetes groups

Identity provider admins can assign metadata to a user, such as group membership or access permissions. Administrators configure what metadata is shared with Teleport. Teleport receives user metadata keys and values as OIDC claims or SAML attributes during signle sign-on redirect flow:

# Alice has an email [email protected] Email is a standard OIDC claim.
email: "[email protected]"
# Alice is a member of groups admins and devs
groups: ["admins", "devs"]
# She can access prod and staging environments
access: {"env": ["prod", "staging"]}

Teleport's roles map OIDC claims or SAML attributes using template variables. Template variable {{external.groups}} will be substituted to the users' group list in the role definition.

kind: role
version: v4
metadata:
  name: group-member
spec:
  allow:
    # For Alice, will be substituted with the list ["admins", "devs"]
    kubernetes_groups: ["{{external.groups}}"]
    # For Alice, will be substituted with ["[email protected]"]
    kubernetes_users: ["{{external.email}}"]

The examples below may include the use of the sudo keyword, token UUIDs, and users with elevated privileges to make following each step easier.

We recommend you follow the best practices to avoid security incidents:

  1. Avoid using sudo in production environments unless it's necessary.
  2. Create new, non-root, users and use test instances for experimenting with Teleport.
  3. You can run many Teleport's services as a non root. For example, auth, proxy, application access, kubernetes access, and database access services can run as a non-root user. Only the SSH/node service requires root access. You will need root permissions (or the CAP_NET_BIND_SERVICE capability) to make Teleport listen on a port numbered < 1024 (e.g. 443)
  4. Follow the "Principle of Least Privilege" (PoLP) and "Zero Admin" best practices. Don't give users permissive roles when giving them more restrictive access,editor roles will do instead.
  5. Save tokens into a file rather than sharing tokens directly as strings.

Create or update this role using tctl:

tctl create -f member.yaml

Assign this role to a user in OIDC or SAML connector:

kind: github
version: v3
metadata:
  # Connector name that will be used with `tsh --auth=github login`
  name: github
spec:
  # Client ID of Github OAuth app
  client_id: client-id
  # Client secret of Github OAuth app
  client_secret: client-secret
  # This name will be shown on UI login screen
  display: Github
  # Change tele.example.com to your domain name
  redirect_url: https://tele.example.com:443/v1/webapi/github/callback
  # Map github teams to kubernetes groups
  teams_to_logins:
    - organization: octocats # Github organization name
      team: admin            # Github team name within that organization
      # List of Kubernetes groups this Github team is allowed to connect to
      # Keep this field as is for now
      logins: ["admins"]
kind: oidc
version: v2
metadata:
  name: auth0
spec:
  redirect_url: https://tele.example.com/v1/webapi/oidc/callback
  client_id: client-id-here
  client_secret: client-secret-here
  issuer_url: https://idp.example.com/
  # request groups scope from OIDC provider
  # read more about scopes here https://auth0.com/docs/scopes/openid-connect-scopes
  scope: [groups]
  claims_to_roles:
    - {claim: "groups", value: "*", roles: ["group-member"]}
kind: saml
version: v2
metadata:
  name: okta
spec:
  acs: https://tele.example.com/v1/webapi/saml/acs
  attributes_to_roles:
  - {name: "groups", value: "*", roles: ["group-member"]}
  entity_descriptor: |
    <?xml !!! Make sure to indent all lines in XML descriptor
    with 4 spaces, otherwise things will not work

Local Users

Local users are mapped to Kubernetes groups using roles:

Specify `kubernetes_groups` property in a role "admins" and

create a user assigned to the role.

tctl users add joe --roles="admins"

Kubernetes labels

Label each cluster with key-value pairs describing the cluster:

Install or upgrade the agent or cluster and set labels:

helm upgrade teleport-agent teleport-kube-agent --set kubeClusterName={CLUSTER?}\ --set proxyAddr=${PROXY?} --set authToken=${TOKEN?} --create-namespace --namespace=teleport-agent\ --set labels.env=prod --set labels.region=us-west-1
kubernetes_service:
  enabled: true
  kube_cluster_name: cookie
  labels:
    env: prod
    region: us-west-1

Limit access to cluster based on the label:

kind: role
version: v4
metadata:
  name: group-member
spec:
  allow:
    # Allow access to kubernetes clusters in production environment
    kubernetes_labels:
      'env': 'prod'

Impersonation

Teleport uses Kubernetes impersonation to map OIDC and SAML users to Kubernetes users and groups.

Here is an example of Kubernetes ClusterRole and ClusterRoleBinding allowing Teleport's ServiceAccount to impersonate users and groups:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: teleport-impersonation
rules:
- apiGroups:
  - ""
  resources:
  - users
  - groups
  - serviceaccounts
  verbs:
  - impersonate
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - "authorization.k8s.io"
  resources:
  - selfsubjectaccessreviews
  verbs:
  - create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: teleport
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: teleport-impersonation
subjects:
- kind: ServiceAccount
  # this should be changed to the name of the Kubernetes ServiceAccount being used
  name: teleport-serviceaccount
  namespace: default

Take a look at the example usage in a Teleport Helm chart

Next steps

Integrate with your identity provider:

Have a suggestion or can’t find something?
IMPROVE THE DOCS