InfoGrab Docs

합류 방법 및 토큰

요약

이 가이드는 Teleport 합류 프로세스의 핵심 개념을 설명하고, 지원되는 모든 합류 방법을 참조하며 보안 속성에 따라 분류합니다. 이 페이지를 읽기 전에 Teleport 핵심 개념에 익숙해야 합니다. Teleport 클러스터에 합류하는 것은 새 Teleport 인스턴스와 Teleport 클러스터에 이미 속해 있는 모든 기존 인스턴스 간의 신뢰를 확립하는 행위입니다.

이 가이드는 Teleport 합류 프로세스의 핵심 개념을 설명하고, 지원되는 모든 합류 방법을 참조하며 보안 속성에 따라 분류합니다. 이 가이드는 각 합류 방법으로 인스턴스를 합류시키는 방법을 단계별로 설명하지 않지만, 가능한 경우 관련 방법 가이드 링크를 제공합니다.

Prerequisite

이 페이지를 읽기 전에 Teleport 핵심 개념에 익숙해야 합니다.

정의#

합류#

Teleport 클러스터에 합류하는 것은 새 Teleport 인스턴스와 Teleport 클러스터에 이미 속해 있는 모든 기존 인스턴스 간의 신뢰를 확립하는 행위입니다. 합류 프로세스가 끝나면 Auth Service가 합류 인스턴스에 대한 인증서에 서명합니다. 해당 인증서는 확립된 신뢰를 나타냅니다. 이를 통해 새로 합류한 인스턴스가 다른 Teleport 인스턴스와 상호 작용할 수 있습니다.

인증서를 요청하려면 인스턴스가 Auth Service에 자신의 신원을 증명해야 합니다. Teleport는 합류 인스턴스가 자신의 진위성을 증명하는 여러 가지 방법을 제공하는데, 이를 합류 방법이라고 합니다.

합류 프로세스는 Teleport 서비스에 유효한 인증서가 없을 때만 발생합니다. 토큰이 인증서로 교환되면 해당 인증서가 이후 모든 연결 시도에 사용됩니다. 대부분의 경우 이는 첫 번째 시작 시 발생합니다.

합류 방법#

합류 방법은 Auth Service가 Teleport 클러스터에 합류를 요청하는 인스턴스가 합법적인지 검증하는 방법입니다. 일부 합류 방법은 범용적인 반면, 다른 방법은 합류 인스턴스의 컨텍스트에 의존합니다. 예를 들어 클라우드 공급자 합류 방법(예: iam, gcp 또는 azure) 또는 CI 공급자(예: github, gitlab, circleci)는 더 유연하고 더 나은 보안 보장을 제공하지만 특정 클라우드 공급자에서 실행되는 합류 인스턴스가 필요합니다.

다른 합류 방법은 다른 보안 보장을 제공할 수 있습니다. 예를 들어 일부 합류 방법은 합류 인스턴스가 갱신 가능한 인증서를 요청하도록 허용하는 반면, 다른 방법은 인스턴스가 인증서를 갱신하기 위해 다시 합류해야 합니다.

합류 방법과 해당 매개변수는 토큰 리소스에 지정됩니다.

토큰#

토큰은 어떤 합류 방법이 어떤 컨텍스트에서 사용될 수 있는지를 지정하는 Teleport 리소스입니다. 예를 들어, 토큰은 SSH 서비스가 AWS 계정 333333333333에 있고 역할 teleport-instance-role을 가정할 수 있는 경우 iam 합류 방법으로 합류할 수 있도록 허용할 수 있습니다:

kind: token
version: v2
metadata:
  name: my-iam-token
spec:
  roles: [Node]
  join_method: iam
  allow:
  - aws_account: "333333333333"
    aws_arn: "arn:aws:sts::333333333333:assumed-role/teleport-instance-role/i-*"
Warning

토큰 이름은 합류 방법에 따라 민감하거나 그렇지 않을 수 있습니다. 시크릿 기반 합류 방법은 토큰 이름이 비밀이어야 합니다. 이러한 경우 토큰 이름을 아는 것만으로도 인스턴스가 클러스터에 합류할 수 있으므로 토큰 이름을 보호해야 합니다.

합류 방법 분류#

시크릿 기반 vs 위임 기반#

시크릿 기반 합류 방법#

시크릿 기반 합류 방법은 범용적입니다: Teleport 서비스는 실행되는 플랫폼/클라우드 공급자에 관계없이 시크릿 기반 합류 방법을 사용할 수 있습니다. 합류 인스턴스는 시크릿을 전송하고 Auth Service는 그것이 알고 있는 것과 일치하는지 검증합니다. 이러한 합류 방법은 본질적으로 시크릿 유출에 취약하며, 가능한 경우 위임 합류 방법을 선호해야 합니다. 시크릿 기반 합류 방법을 사용해야 하는 경우, 토큰 유출 위험을 줄이기 위해 단기 토큰(예: 1시간만 유효)을 사용하는 것이 좋습니다.

시크릿 기반 합류 방법:

Warning

Teleport는 하위 호환성을 위해 정적 토큰을 지원하지만, 사용을 피해야 합니다.

위임 합류 방법#

위임 합류 방법은 합류 인스턴스의 컨텍스트와 제3자를 통해 신뢰를 확립합니다. 제3자는 클라우드 공급자, CI 플랫폼 또는 컨테이너 런타임일 수 있습니다. 이러한 방법은 모든 인스턴스에 사용할 수 없지만(예: Raspberry Pi에서 SSH 에이전트 합류는 불가능), 가능한 경우 선호해야 합니다.

위임 합류 방법은 더 세분화된 제어를 제공할 수도 있습니다. 예를 들어, 클라우드 공급자 기반 합류 방법은 가용성 영역, 서비스 계정 또는 클라우드 계정 ID에 따라 인스턴스의 합류를 허용할 수 있습니다.

위임 합류 방법:

갱신 가능 vs 갱신 불가능#

사용된 합류 방법에 따라 Auth Service는 갱신 가능하거나 갱신 불가능한 인증서를 발급할 수 있습니다.

인증서가 만료되려고 할 때, 갱신 가능한 인증서를 가진 인스턴스는 토큰을 다시 사용하지 않고도 새 인증서를 요청할 수 있습니다. 일반적으로 시크릿 기반 합류 방법은 시크릿 토큰이 민감하고 일반적으로 단기이기 때문에 갱신 가능한 인증서를 제공합니다. 단일 합류로 인스턴스는 무기한으로 클러스터의 일부로 남아 있을 수 있습니다.

갱신 가능한 합류 방법:

갱신 불가능한 인증서를 가진 노드는 만료 전에 새 인증서를 얻기 위해 다시 합류해야 합니다. 인스턴스는 자신이 합법적임을 다시 증명해야 합니다. 갱신 불가능한 합류 방법은 인스턴스 인증서를 훔친 공격자가 Teleport 클러스터에 대한 접근을 유지할 수 없음을 보장합니다. 이러한 합류 방법은 CI/CD 파이프라인이나 컨테이너화된 환경과 같은 임시 워크로드에 더 안전하고 더 적합한 것으로 간주될 수 있습니다.

갱신 불가능한 합류 방법:

토큰 리소스 레퍼런스#

토큰 리소스에는 모든 합류 방법에 대한 다음과 같은 공통 필드가 있습니다:

# token.yaml
kind: token
version: v2
metadata:
  name: my-token-name
spec:
  # 시스템 역할은 합류하는 Teleport 인스턴스가 실행할 수 있는 서비스를 설명합니다.
  # 이러한 역할은 인스턴스 인증서에 기록됩니다. 변경하려면(예: SSH 노드에 애플리케이션 접근 추가):
  # - 토큰을 편집하여 역할 업데이트(예: "App" 추가)
  # - Teleport 인스턴스 등록 해제
  # - 새 서비스를 활성화하도록 설정 수정(여기서는 "app_service.enabled")
  # - 인스턴스를 다시 합류시킴
  #
  # 필요한 최소 시스템 역할 세트를 사용해야 합니다.
  # 일반적인 역할:
  # - SSH 서비스를 위한 "Node"
  # - Proxy 서비스를 위한 "Proxy"
  # - Kubernetes 서비스를 위한 "Kube"
  # - Application 서비스를 위한 "App"
  # - Database 서비스를 위한 "Db"
  # - Windows Desktop 서비스를 위한 "WindowsDesktop"
  # - Discovery 서비스를 위한 "Discovery"
  # - 머신 및 워크로드 아이덴티티를 위한 "Bot"(설정 시 토큰에 "spec.bot_name"을 설정해야 함)
  # - Jamf 서비스를 위한 "MDM"
  roles:
    - Node
    - App
  join_method: gcp
  # 머신 및 워크로드 아이덴티티에 토큰이 사용되는 경우에만 봇 이름을 설정합니다.
  # 설정 시 토큰에 "Bot" 역할도 있어야 합니다.
  bot_name: my-bot
  # SuggestedLabels는 이 토큰을 사용하여 클러스터에 등록할 때 리소스가 설정해야 하는 레이블 세트입니다.
  # 현재 node-join 스크립트만 제안에 따라 설정을 생성합니다.
  suggested_labels:
    teams: ["sales-eng", "eng", "qa"]
    application: ["demo-product"]
  # SuggestedAgentMatcherLabels는 디스커버리 에이전트가 리소스를 매칭하는 데 사용할 레이블 세트입니다.
  # 에이전트가 이 토큰을 사용할 때 에이전트는 이러한 레이블과 일치하는 리소스를 모니터링해야 합니다.
  # 데이터베이스의 경우, 이는 `db_service.resources.labels`에 레이블을 추가하는 것을 의미합니다.
  # 현재 node-join 스크립트만 제안에 따라 설정을 생성합니다.
  suggested_agent_matcher_labels:
    teams: ["sales-eng"]

합류 방법#

정적 토큰#

Warning

이 합류 방법은 장기 토큰이 도난당하고 재사용될 수 있어 본질적으로 덜 안전합니다. 이에 의존하면 Teleport 사용의 보안 이점이 크게 감소합니다. 사용을 강력히 권장하지 않습니다. 대신 일시적 토큰을 사용해야 합니다.

정적 토큰은 Auth Service 설정(teleport.yaml)에 정의된 토큰입니다. 토큰 이름은 비밀로 유지해야 합니다. 이를 알면 Teleport 클러스터에 인스턴스를 합류시킬 수 있습니다.

auth_service:
    enabled: true
    # 클러스터에 새 인스턴스를 추가하기 위해 미리 정의된 토큰. 각 토큰은
    # 새 노드가 가정할 수 있는 역할을 지정합니다. 더 안전한 방법으로
    # 인스턴스를 추가하려면 `tctl nodes add --ttl` 명령을 사용하여 자동 만료
    # 토큰을 생성합니다.
    #
    # `pwgen`과 같은 도구를 사용하여 32바이트 이상의 충분히 무작위인
    # 토큰을 생성하는 것이 좋습니다.
    tokens:
        - "proxy,node:xxxxx"
        - "auth:yyyy"
        - "discovery,app,db:zzzzz"

일시적 토큰#

일시적 토큰은 CLI 또는 Teleport API를 통해 동적으로 생성되는 시크릿 토큰입니다. 시간 제한이 있으며 일반적으로 인스턴스를 Teleport 클러스터에 합류시키기 직전에 생성됩니다.

CLI로 생성할 수 있습니다(지정하지 않으면 강력한 무작위 값이 선택되고, 기본 TTL은 30분):

$ tctl tokens add --type discovery,app --ttl 15m

또는 Teleport 리소스로:

kind: token
version: v2
metadata:
  expires: "2023-11-24T21:45:40.104524Z"
  name: (=presets.tokens.first=)
spec:
  join_method: token
  roles:
    - Discovery
    - App

머신 및 워크로드 아이덴티티 봇이 일시적 합류 토큰을 사용하면 토큰이 삭제됩니다.

Upgrade to Bound Keypair

새 봇 배포는 bound_keypair 합류 방법으로 업그레이드를 고려해야 합니다.

Bound Keypair: bound_keypair#

Bound Keypair 토큰은 보안과 유연성을 향상시키는 시크릿 기반 합류 방법의 대안입니다. 영구 스토리지가 있는 플랫폼에서 가장 잘 사용되지만, 시크릿을 영구적으로 저장할 수 있는 모든 환경에서 사용할 수 있습니다.

이 합류 방법은 TPM이 없는 온프렘 환경이나 특화된 위임 합류 방법이 없는 클라우드 플랫폼에 권장됩니다.

bound_keypair는 인증서가 자주 갱신되는 Machine & Workload ID 봇을 위해 설계되었으며 가장 적합하지만, 장기 인증서가 발급되는 표준 Teleport 에이전트 합류(Teleport v18.8부터 지원)에도 사용할 수 있습니다. 에이전트에 대한 Bound Keypair는 사용 전에 확인해야 할 특정 제한사항이 있습니다.

kind: token
version: v2
metadata:
  name: example-token
spec:
  roles: [Bot]
  join_method: bound_keypair
  bot_name: example

  # Fields related to the bound keypair joining process.
  bound_keypair:
    # Fields related to the initial join attempt.
    onboarding:
      # If set to a public key in SSH authorized_keys format, the
      # joining client must have the corresponding private key to join. This
      # keypair may be created using `tbot keypair create`. If set,
      # `registration_secret` and `must_register_before` are ignored.
      initial_public_key: ""

      # If set to a secret string value, a client may use this secret to perform
      # the first join without pre-registering a public key in
      # `initial_public_key`. If unset and no `initial_public_key` is provided,
      # a random value will be generated automatically into
      # `.status.bound_keypair.registration_secret`.
      registration_secret: ""

      # If set to an RFC 3339 timestamp, attempts to register via
      # `registration_secret` will be denied once the timestamp has elapsed. If
      # more time is needed, this field can be edited to extend the registration
      # period.
      must_register_before: ""

    # Fields related to recovery after certificates have expired.
    recovery:
      # The maximum number of allowed recovery attempts. This value may
      # be raised or lowered after creation to allow additional recovery
      # attempts should the initial limit be exhausted. If `mode` is set to
      # `standard`, recovery attempts will only be allowed if
      # `.status.bound_keypair.recovery_count` is less than this limit. This
      # limit is not enforced if `mode` is set to `relaxed` or `insecure`. This
      # value must be at least 1 to allow for the initial join during
      # onboarding, which counts as a recovery.
      limit: 1

      # The recovery rule enforcement mode. Valid values:
      # - standard (or unset): all configured rules enforced. The recovery limit
      #   and client join state are required and verified. This is the most
      #   secure recovery mode.
      # - relaxed: recovery limit is not enforced, but client join state is
      #   still required. This effectively allows unlimited recovery attempts,
      #   but client join state still helps mitigate stolen credentials.
      # - insecure: neither the recovery limit nor client join state are
      #   enforced. This allows any client with the private key to join freely.
      #   This is less secure, but can be useful in certain situations, like in
      #   otherwise unsupported CI/CD providers. This mode should be used with
      #   care, and RBAC rules should be configured to heavily restrict which
      #   resources this identity can access.
      mode: "standard"

    # If set to an RFC 3339 timestamp, once elapsed, a keypair rotation will be
    # forced on next join if it has not already been rotated. The most recent
    # rotation is recorded in `.status.bound_keypair.last_rotated_at`.
    rotate_after: ""

AWS IAM 역할: iam#

IAM 합류 방법은 EC2 인스턴스에 연결된 IAM 역할과 같이 IAM 자격 증명에 접근할 수 있는 곳에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. 특정 권한이나 IAM 정책은 필요하지 않습니다: 정책이 연결되지 않은 IAM 역할로 충분합니다. Teleport Auth Service에는 IAM 자격 증명이 필요하지 않습니다.

이는 AWS에서 실행되는 워크로드에 합류하는 데 권장되는 방법입니다.

  # token.yaml
  kind: token
  version: v2
  metadata:
    # the token name is not a secret because instances must prove that they are
    # running in your AWS account to use this token
    name: iam-token
  spec:
    # use the minimal set of roles required (e.g. Node, App, Kube, DB, WindowsDesktop)
    roles: [Node]
    
    # set the join method allowed for this token
    join_method: iam
    
    allow:
      # specify the AWS account which Teleport processes may join from
      - aws_account: "111111111111"
      # multiple allow rules are supported
      - aws_account: "222222222222"
      # aws_arn is optional and allows you to restrict the IAM role of joining
      # Teleport processes
      - aws_account: "333333333333"
        aws_arn: "arn:aws:sts::333333333333:assumed-role/teleport-node-role/i-*"
    ```
<!-- /INCLUDE:ENGLISH -->

<div class="admonition note"><div class="admonition-title">See Also</div>

- [AWS IAM 역할을 통한 서비스 합류하기](../../installation/agents/aws-iam.mdx).
- [AWS에서 머신  워크로드 아이덴티티 배포하기](../../machine-workload-identity/deployment/aws.mdx)

</div>

### AWS EC2 신원 문서: `ec2`

EC2 합류 방법은 EC2 인스턴스에서 실행되는 모든 Teleport 프로세스에서 사용할  있습니다. EC2 인스턴스당 하나의 Teleport 프로세스만 EC2 합류 방법을 사용할  있습니다.

Teleport Auth Service에는 `ec2:DescribeInstances` 권한이 있는 IAM 자격 증명이 필요합니다. 클러스터에 합류하는 Teleport 프로세스에는 IAM 자격 증명이 필요하지 않습니다.

<div class="admonition warning"><div class="admonition-title">Warning</div>

EC2 합류 방법은 Teleport Enterprise Cloud  Teleport Team에서 사용할  없습니다. Teleport Enterprise Cloud  Team 고객은 [IAM 합류 방법](#aws-iam-role-iam) 또는 [일시적 시크릿 토큰](#ephemeral-tokens)을 사용할  있습니다.

</div>

<!-- INCLUDE:ENGLISH:docs/pages/includes/provision-token/ec2-spec.mdx -->
```yaml
# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your AWS account to use this token
  name: ec2-token
spec:
  # use the minimal set of roles required (e.g. Node, App, Kube, DB, WindowsDesktop)
  roles: [Node]

  # set the join method allowed for this token
  join_method: ec2

  # aws_iid_ttl is the amount of time after the EC2 instance is launched during
  # which it should be allowed to join the cluster. Use a short TTL to decrease
  # the risk of stolen EC2 Instance Identity Documents being used to join your
  # cluster.
  #
  # When launching your first Teleport process using the EC2 join method, you may need to
  # temporarily configure a higher `aws_iid_ttl` value so that you have time
  # to get Teleport set up and configured. This feature works best once Teleport
  # is configured in an EC2 AMI to start automatically on launch.
  aws_iid_ttl: 5m

  allow:
  - aws_account: "111111111111" # your AWS account ID
    aws_regions: # use the minimal set of AWS regions required
    - us-west-1
    - us-west-2

Azure 관리 신원: azure#

Azure 합류 방법은 Azure Virtual Machine에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다.

# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your Azure subscription to use this token
  name: azure-token
spec:
  # use the minimal set of roles required
  roles: [Node]
  join_method: azure
  azure:
    allow:
      # specify the Azure subscription which Teleport processes may join from
      - subscription: 11111111-1111-1111-1111-111111111111
      # multiple allow rules are supported
      - subscription: 22222222-2222-2222-2222-222222222222
      # resource_groups is optional and allows you to restrict the resource group of
      # joining Teleport processes
      - subscription: 33333333-3333-3333-3333-333333333333
        resource_groups: ["group1", "group2"]

Azure Devops: azure_devops#

Azure DevOps는 Azure DevOps 파이프라인에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. 이 합류 방법은 일반적으로 장기 시크릿 없이 Azure DevOps 파이프라인에서 Teleport 보호 리소스에 접근하기 위해 머신 및 워크로드 아이덴티티와 함께 사용됩니다.

# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your Azure DevOps organization to use this token
  name: azure-devops-token
spec:
  roles: [Bot]
  join_method: azure_devops
  bot_name: my-bot
  azure_devops:
    # the UUID of the Azure DevOps organization that the pipeline will be
    # joining from. Joins from pipelines in other organizations will be
    # rejected.
    organization_id: 11111111-1111-1111-1111-111111111111
    # a list of rules that determine which Azure DevOps pipelines can use this
    # token to join. At least one must be specified, and each rule must define
    # at least the `sub`, `project_name` or `project_id` field.
    allow:
        # the `sub` field is a unique identifier for the pipeline in Azure DevOps.
        # It is a combination of the organization, project, and pipeline name.
        # The format is `p://<organization>/<project>/<pipeline>`.
      - sub: p://my-organization/my-project/my-pipeline
        # the `project_name` field is the name of the Azure DevOps project the
        # pipeline is in.
        project_name: my-project
        # the `pipeline_name` field is the name of the Azure DevOps pipeline.
        pipeline_name: my-pipeline
        # the `project_id` field is the unique identifier for the Azure DevOps
        # project the pipeline is in.
        project_id: 22222222-2222-2222-2222-222222222222
        # the `definition_id` is the unique identifier for the pipeline
        # definition within the Azure DevOps project.
        definition_id: 1
        # the `repository_uri` is the URI of the source code repository that
        # the pipeline is running against.
        repository_uri: https://github.com/gravitational/teleport.git
        # the `repository_version` is the commit SHA of the source code that
        # the pipeline is running against.
        repository_version: e6b9eb29a288b27a3a82cc19c48b9d94b80aff36
        # the `repository_ref` is the branch or tag of the source code that
        # the pipeline is running against.
        repository_ref: refs/heads/main

Env0: env0#

Env0 합류 방법은 Env0 클라우드 환경에서 실행되는 워크로드에서 사용할 수 있습니다. 토큰이 러너 환경에 발급되려면 "Enable OIDC during deployments" 옵션을 활성화해야 합니다.

이 합류 방법은 일반적으로 Teleport Terraform 공급자가 Env0 클라우드 환경에서 Teleport에 인증하는 데 사용됩니다. 다른 플랫폼에서 Terraform 실행에 합류하는 데는 사용할 수 없으며 대신 전용 합류 방법을 사용해야 합니다.

env0 합류 방법은 Teleport v18.4.0 이상이 필요합니다.

kind: token
version: v2
metadata:
  name: env0
spec:
  roles: [Bot]
  join_method: env0

  # This must match a bot name, created either with `tctl bots add` or by
  # creating a `bot` resource.
  bot_name: env0

  env0:
    allow:
      # organization_id and one of either project_name or project_id must be
      # set. All other fields are optional and only checked if set.
      # For more information on possible values, see Env0's documentation:
      # https://docs.envzero.com/guides/integrations/oidc-integrations#format-of-the-openid-connect-id-token
      - organization_id: "00000000-0000-0000-0000-000000000000"

        # A unique project identifier. Either this field or `project_name` must
        # be set.
        project_id: "00000000-0000-0000-0000-000000000000"

        # The project name. Either this field or `project_id` must be set.
        project_name: ExampleProject

        # A unique template identifier.
        template_id: "00000000-0000-0000-0000-000000000000"

        # The template name, optional.
        template_name: ExampleTemplate

        # The unique environment ID.
        environment_id: "00000000-0000-0000-0000-000000000000"

        # The environment name.
        environment_name: ExampleEnvironment

        # The workspace name.
        workspace_name: WorkspaceName

        # The deployment type, including "deploy", "destroy", "prPlan", "task"
        deployment_type: ""

        # The email address of the user that started the deployment.
        deployer_email: ""

        # A custom value provided via the `ENV0_OIDC_TAG` environment variable
        env0_tag: ""

GCP 서비스 계정: gcp#

GCP 합류 방법은 GCP VM에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. VM에는 서비스 계정이 할당되어 있어야 합니다(기본 서비스 계정도 괜찮습니다). 클러스터에 합류하는 Teleport 프로세스에는 IAM 역할이 필요하지 않습니다.

# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your GCP project to use this token
  name: gcp-token
spec:
  # use the minimal set of roles required (e.g. Node, Proxy, App, Kube, DB, WindowsDesktop)
  roles: [Node]

  # set the join method allowed for this token
  join_method: gcp

  gcp:
    allow:
      # The GCP project ID(s) that VMs can join from.
      - project_ids: ["example-project-id"]
        # (Optional) The locations that VMs can join from. Note: both regions and
        # zones are accepted.
        locations: ["us-west1", "us-west2-a"]
        # (Optional) The email addresses of service accounts that VMs can join
        # with.
        service_accounts: ["example@example.com"]

GitHub Actions: github#

Teleport는 GitHub 호스팅 및 자체 호스팅 GitHub Actions 러너와 GitHub Enterprise Server 모두에서 안전한 합류를 지원합니다. 이 합류 방법은 일반적으로 GitHub Actions 파이프라인에서 Teleport 보호 리소스에 접근하기 위해 머신 및 워크로드 아이덴티티와 함께 사용됩니다.

kind: token
version: v2
metadata:
  # name identifies the token. When configuring a bot or node to join using this
  # token, this name should be specified.
  name: github-token
spec:
  # For Machine & Workload Identity via GitHub joining, roles will always be
  # "Bot" and  join_method will always be "github".
  roles: [Bot]
  join_method: github

  # bot_name specifies the name of the bot that this token will grant access to
  # when it is used.
  bot_name: github-demo

  github:
    # enterprise_server_host allows joining from GitHub Actions workflows in a
    # GitHub Enterprise Server instance. For normal situations, where you are
    # using github.com, this option should be omitted. If you are using GHES,
    # this value should be configured to the hostname of your GHES instance.
    enterprise_server_host: ghes.example.com

    # static_jwks allows the JSON Web Key Set (JWKS) used to verify the token
    # issued by GitHub Actions to be overridden. This can be used in scenarios
    # where the Teleport Auth Service is unable to reach a GHES server.
    #
    # This field is optional and should only be used with GitHub Enterprise
    # Server. When unspecified, the JWKS will be fetched automatically using the
    # GHES server specified in `enterprise_server_host`.
    static_jwks: |
      {"keys":[--snip--]}

    # enterprise_slug allows the slug of a GitHub Enterprise organisation to be
    # included in the expected issuer of the OIDC tokens. This is for
    # compatibility with the include_enterprise_slug option in GHE.
    #
    # This field should be set to the slug of your Github Enterprise organization if this is enabled. If
    # this is not enabled, then this field must be left empty. This field cannot
    # be specified if `enterprise_server_host` is specified.
    #
    # See https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#customizing-the-issuer-value-for-an-enterprise
    # for more information about customized issuer values.
    enterprise_slug: slug

    # allow is an array of rule configurations for what GitHub Actions workflows
    # should be allowed to join. All options configured within one allow entry
    # must be satisfied for the GitHub Actions run to be allowed to join. Where
    # multiple allow entries are specified, any run which satisfies all of the
    # options within a single entry will be allowed to join.
    #
    # An allow entry must include at least one of:
    # - repository
    # - repository_owner
    # - sub
    allow:
      - # repository is a fully qualified (e.g. including the owner) name of a
        # GitHub repository.
        repository: gravitational/teleport
        # repository_owner is the name of an organization or user that a
        # repository belongs to.
        repository_owner: gravitational
        # workflow is the exact name of a workflow as configured in the GitHub 
        # Action workflow YAML file.
        workflow: my-workflow
        # environment is the environment associated with the GitHub Actions run.
        # If no environment is configured for the GitHub Actions run, this will
        # be empty.
        environment: production
        # actor is the GitHub username that caused the GitHub Actions run,
        # whether by committing or by directly despatching the workflow.
        actor: octocat
        # ref is the git ref that triggered the action run.
        ref: refs/heads/main
        # ref_type is the type of the git ref that triggered the action run.
        ref_type: branch
        # sub is a concatenated string of various attributes of the workflow 
        # run. GitHub explains the format of this string at:
        # https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims
        sub: repo:gravitational/example-repo:environment:production

GitHub Actions 헬퍼#

Teleport 머신 및 워크로드 아이덴티티와 GitHub Actions를 활용할 때 워크플로에서 사용할 수 있는 일련의 기성품 GitHub Actions를 제공합니다.

이러한 개별 액션에 대한 자세한 내용은 GitHub 저장소에서 확인할 수 있습니다:

이러한 액션을 사용하는 데 문제가 있으면 소스 저장소에서 이슈를 제기하십시오: https://github.com/teleport-actions/root.

CircleCI: circleci#

이 합류 방법은 일반적으로 Circle CI 파이프라인에서 Teleport 보호 리소스에 접근하기 위해 머신 및 워크로드 아이덴티티와 함께 사용됩니다.

kind: token
version: v2
metadata:
  name: example-bot
spec:
  roles: [Bot]
  join_method: circleci
  bot_name: example
  circleci:
    organization_id: $ORGANIZATION_ID
    # allow specifies the rules by which the Auth Service determines if `tbot`
    # should be allowed to join.
    allow:
      - # CircleCI context id. See the CircleCI Machine & Workload Identity
        # guide to learn how to create a context and recover its ID.
        context_id: 00000000-0000-0000-0000-000000000000
        # CircleCI projectID.
        project_id: 1234

GitLab: gitlab#

Teleport는 클라우드 호스팅 및 자체 호스팅 GitLab 인스턴스 모두에서 안전한 합류를 지원합니다. 최소 지원 GitLab 버전은 15.7입니다.

이 합류 방법은 일반적으로 Gitlab CI 파이프라인에서 Teleport 보호 리소스에 접근하기 위해 머신 및 워크로드 아이덴티티와 함께 사용됩니다.

kind: token
version: v2
metadata:
  # name identifies the token. When configuring a bot or node to join using this
  # token, this name should be specified.
  name: gitlab-demo
spec:
  # The Bot role indicates that this token grants access to a bot user, rather
  # than allowing a node to join.
  roles: [Bot]
  # join_method for GitLab joining will always be "gitlab".
  join_method: gitlab

  # bot_name specifies the name of the bot that this token will grant access to
  # when it is used.
  bot_name: gitlab-demo

  gitlab:
    # domain should be the domain of your GitLab instance. If you are using
    # GitLab's cloud hosted offering, omit this field entirely.
    domain: gitlab.example.com
    # static_jwks allows the JSON Web Key Set (JWKS) used to verify the token
    # issued by GitLab to be overridden. This can be used in scenarios
    # where the Teleport Auth Service is unable to reach a GitLab server.
    #
    # This field is optional. When unspecified, the JWKS will be fetched
    # automatically using the value from the domain field and OIDC.
    static_jwks: |
      {"keys":[--snip--]}
    # allow is an array of rule configurations for what GitLab CI jobs should be
    # allowed to join. All options configured within one allow entry
    # must be satisfied for the GitLab CI run to be allowed to join. Where
    # multiple allow entries are specified, any job which satisfies all of the
    # options within a single entry will be allowed to join.
    #
    # An allow entry must include at least one of:
    # - project_path
    # - namespace_path
    # - sub
    # This ensures that GitLab CI runs in other GitLab user's projects are not
    # able to access your Teleport cluster.
    allow:
      # project_path restricts joins to jobs that originate within the
      # specified project.
      #
      # This field supports glob-style matching:
      # - Use '*' to match zero or more characters.
      # - Use '?' to match any single character.
      - project_path: my-user/my-project
        # namespace_path restricts joins to any run within project that exists
        # within the specified namespace. A namespace will either be a username
        # or the name of a group.
        #
        # This field supports glob-style matching:
        # - Use '*' to match zero or more characters.
        # - Use '?' to match any single character.
        namespace_path: my-user
        # pipeline_source restricts joins to jobs triggered by certain criteria,
        # e.g triggered through the web interface.
        pipeline_source: web
        # environment restricts joins to jobs that are associated with the
        # specified environment
        environment: production
        # ref_type restricts joins to jobs that were triggered by a specific
        # type of git reference. Either `branch` or `tag`.
        ref_type: branch
        # ref restricts joins to jobs that were triggered by a specific git
        # reference. Combine this with `ref_type` to create allow rules that
        # can only be triggered by a specific branch or tag.
        #
        # This field supports glob-style matching:
        # - Use '*' to match zero or more characters.
        # - Use '?' to match any single character.
        ref: main
        # sub is a single string that concatenates the project_path, ref_type
        # and ref. This can be used to restrict joins using a single string,
        # whilst also describing a specific project and git ref.
        #
        # It is better to use the individual fields, as it is easy to mis-format
        # the sub string.
        #
        # This field supports glob-style matching:
        # - Use '*' to match zero or more characters.
        # - Use '?' to match any single character.
        sub: project_path:my-user/my-project:ref_type:branch:ref:main
        # user_login restricts joins to jobs that were triggered by a specific
        # username.
        user_login: octocat
        # user_email restricts joins to jobs that were triggered by a specific
        # user with the given email
        user_email: octo.cat@example.com
        # ref_protected if set to true restricts joins to jobs running against a
        # protected ref.
        # If omitted, the protection status of the ref is not checked.
        ref_protected: true
        # environment_protected if set to true restricts joins to jobs running
        # against a protected ref.
        # If omitted, the protection status of the ref is not checked.
        environment_protected: true
        # ci_config_sha restricts joins to jobs that are using a specific
        # commit of CI configuration.
        ci_config_sha: ffffffffffffffffffffffffffffffffffffffff
        # ci_config_ref_uri restricts joins to jobs that are using a specific
        # CI configuration source.
        ci_config_ref_uri: gitlab.example.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main
        # deployment_tier restricts joins to jobs that are deploying to a
        # specific deployment_tier.
        deployment_tier: production
        # project_visibility restricts joins to jobs that are running against a
        # project with a specific visibility configuration.
        project_visibility: public

Kubernetes: kubernetes#

Kubernetes 합류 방법은 세 가지 변형이 있습니다:

Kubernetes 인클러스터#

Kubernetes 인클러스터 합류는 Auth Service와 동일한 Kubernetes 클러스터에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. Kubernetes ServiceAccount 토큰을 사용하여 파드 신원을 검증합니다. 이 방법은 일반적으로 Kubernetes 클러스터 내에서만 접근할 수 있는 Kubernetes TokenReview API에 의존합니다. 이 제한으로 인해 이 합류 방법은 Kubernetes의 자체 호스팅 Teleport 클러스터에서만 사용할 수 있습니다.

파드가 Terminated 상태에 들어가면 토큰이 즉시 취소되므로 가능한 경우 이 방법을 선호해야 합니다.

# token.yaml
kind: token
version: v2
metadata:
  # The token name is not a secret as the Kubernetes join method relies on the
  # Kubernetes signature to establish trust and not on the join token name.
  name: kubernetes-token
  # set a long expiry time, the default for tokens is only 30 minutes
  expires: "2050-01-01T00:00:00Z"
spec:
  # Use the minimal set of system roles required.
  roles: [App]

  # set the join method allowed for this token
  join_method: kubernetes
  
  kubernetes:
    # If type is not specified, it defaults to in_cluster
    type: in_cluster
    allow:
      # Service account names follow the format "namespace:serviceaccountname".
      - service_account: "teleport-agent:teleport-app-service"

Kubernetes JWKS#

Kubernetes JWKS 합류는 Kubernetes에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. Auth Service가 Kubernetes에서 실행될 필요가 없으므로 이 방법은 Teleport Cloud를 포함한 모든 Teleport 클러스터에서 사용할 수 있습니다. 이 합류 방법은 공개 Kubernetes 서명 키를 내보내고 이를 사용하여 Kubernetes SA 토큰 서명을 검증함으로써 작동합니다. 서명 검증은 Kubernetes에 접근하지 않고 Auth Service에서 수행할 수 있습니다.

kind: token
version: v2
metadata:
  name: example
spec:
  roles: [App]
  join_method: kubernetes
  kubernetes:
    # static_jwks configures the Auth Service to validate the JWT presented by
    # `tbot` using the public key from a statically configured JWKS.
    type: static_jwks
    static_jwks:
      jwks: |
        # Place the kubernetes JWKS here (`kubectl get --raw /openid/v1/jwks`)
        {"keys":[--snip--]}
    # allow specifies the rules by which the Auth Service determines if the node
    # should be allowed to join.
    allow:
      - service_account: "namespace:serviceaccount"
Warning

Kubernetes CA를 교체한 후 새 Kubernetes 서명 키를 포함하도록 Kubernetes JWKS 토큰을 업데이트해야 합니다(spec.kubernetes.static_jwks.jwks 필드 업데이트).

Kubernetes OIDC#

Kubernetes OIDC 합류는 클러스터가 공개적으로 접근 가능한 OIDC 호환 발급자에서 서비스 계정 토큰을 발급하는 Kubernetes에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다.

이 기능은 Kubernetes 1.21에서 추가된 Kubernetes 서비스 계정 발급자 디스커버리 기능을 사용하여 Kubernetes 워크로드를 검증합니다. Amazon EKS와 같은 일부 공급자는 OIDC 합류를 활성화하기 위해 추가 설정이 필요할 수 있습니다.

위에 설명된 static_jwks 변형과 달리, 이 방법은 업스트림 공급자에서 JWKS 키를 동적으로 가져오며 키가 교체되더라도 재설정이 필요하지 않습니다. EKS와 같은 공급자는 키를 자주 교체합니다. 그러나 모든 Kubernetes 구현에 접근 가능한 OIDC 엔드포인트가 있는 것은 아닙니다.

Supported Teleport Version

Kubernetes OIDC 합류를 사용하려면 Teleport 클러스터가 최소 버전 18.1.5를 실행해야 합니다.

kind: token
version: v2
metadata:
  name: example
spec:
  roles: [App]
  join_method: kubernetes
  kubernetes:
    # oidc configures the Auth Service to validate the JWT presented by `tbot`
    # using the public keys published by the configured OIDC issuer.
    type: oidc
    oidc:
      # Issuer must be a fully-qualified HTTPS URL and may vary between
      # providers.
      issuer: https://oidc.eks.us-west-2.amazonaws.com/id/my-cluster
    # allow specifies the rules by which the Auth Service determines if the node
    # should be allowed to join.
    allow:
      - service_account: "namespace:serviceaccount"

Trusted Platform Module: tpm#

The tpm join method is a secure way for Bots and Agents to authenticate with the Teleport Auth Service without using any shared secrets. Instead of using a shared secret, the unique identity of the host's Trusted Platform Module (TPM) and public key cryptography is used to authenticate the host.

In environments where there is no other form of identity available to machines, e.g on-prem, this is the most secure method for joining. It avoids the need to distribute a shared secret as is needed for the token join method.

A Trusted Platform Module (TPM) is a secure, physical cryptoprocessor that is installed on a host. TPMs can store cryptographic material and perform a number of cryptographic operations, without exposing the cryptographic material to the operating system. Each TPM has a unique key pair burned-in known as the Endorsement Key (EK). This key does not change, even if the host operating system is reinstalled.

Some TPMs also contain an X.509 certificate for this key pair that is signed by the manufacturer's CA. This is known as the EK Certificate (EKCert). This certificate can be used by the TPM to prove to a third-party (who trusts the manufacturer's CA) that the TPM is genuine and abides by the TPM specification.

When using the tpm join method, you must first query the TPM's public key and then create a join token that explicitly allows this public key. To list information about the detected TPM, run the teleport tpm identify command.

If you have a large number of hosts, it may make sense to use automation tooling such as Ansible to query the TPMs across your fleet and then generate join tokens.

kind: token
version: v2
metadata:
  # name identifies the token. When configuring a bot or node to join using this
  # token, this name should be specified.
  name: tpm-token
spec:
  # For Machine & Workload Identity via TPM joining, roles will always be "Bot"
  # and join_method will always be "tpm".
  roles: [Bot]
  join_method: tpm

  # bot_name specifies the name of the bot that this token will grant access to
  # when it is used.
  bot_name: tpm-demo

  # tpm specifies the TPM join method specific configuration for this token.
  tpm:
    # ekcert_allowed_cas is a list of CA certificates that will be used to
    # validate TPM EKCerts. These should be PEM wrapped.
    #
    # When specified, joining TPMs must present an EKCert signed by one of the
    # specified CAs. TPMs that do not present an EKCert will be not permitted to
    # join.
    #
    # When unspecified, TPMs will be allowed to join with either an EKCert or an
    # EKPubHash.
    ekcert_allowed_cas:
      - |
        -----BEGIN CERTIFICATE-----
        ... CA Certificate Data ...
        -----END CERTIFICATE-----
    # allow is a list of Rules, the presented TPM must match one allow rule to
    # be permitted to join using this token.
    allow:
        # description is a human-readable description of the rule. It has no
        # bearing on whether a TPM is allowed to join, but can be used to
        # associate a rule with a specific host (e.g the asset tag of the server
        # in which the TPM resides).
      - description: "example-build-server-100"
        # ek_public_hash is the SHA256 hash of the EKPub marshaled in PKIX format
        # and encoded in hexadecimal. This value will also be checked when a TPM
        # has submitted an EKCert, and the public key in the EKCert will be used
        # for this check.
        ek_public_hash: "d4b4example6fabfc568d74f2example6c35a05337d7af9a6example6c891aa6"
        # ek_certificate_serial is the serial number of the EKCert in hexadecimal
        # with colon separated nibbles. This value will not be checked when a TPM
        # does not have an EKCert configured.
        ek_certificate_serial: "01:23:45:67:89:ex:am:pl:e0:23:45:67:89:ab:cd:ef"

Terraform Cloud: terraform_cloud#

이 합류 방법은 Terraform Cloud 워크로드 신원을 사용하여 인증하는 데 사용됩니다. 일반적으로 HCP Terraform 또는 자체 호스팅 Terraform Enterprise에서 Teleport Terraform 공급자에 의해 사용됩니다. 다른 플랫폼에서 Terraform 실행에 합류하는 데는 사용할 수 없으며 대신 전용 합류 방법을 사용해야 합니다.

Enterprise

자체 호스팅 Terraform Enterprise 지원은 Teleport Enterprise가 필요합니다.

kind: token
version: v2
metadata:
  name: terraform
spec:
  roles: [Bot]
  join_method: terraform_cloud

  # This must match a bot name, created either with `tctl bots add` or by
  # creating a `bot` resource.
  bot_name: terraform

  terraform_cloud:
    # Manually override the expected audience. If unset, defaults to the
    # Teleport cluster name. It is not recommended to override this value.
    audience: ''

    # Specify the hostname of a Terraform Enterprise instance. Overriding this
    # value to use Terraform Enterprise requires Teleport Enterprise.
    # If unset, refers to the public `app.terraform.io` instance.
    hostname: ''

    allow:
      # At least one of `organization_name` or `organization_id` must be set.
      # Values are case and whitespace sensitive.
      - organization_name: OrgName
        organization_id: org-foo

        # At least one of `project_name`, `project_id`, `workspace_name`, or
        # `workspace_id` must also be set.
        project_name: ProjectName
        project_id: prj-bar

        # If no `workspace_name` or `workspace_id` are set, all workspaces
        # within the specified project will be allowed to join.
        workspace_name: WorkspaceName
        workspace_id: ws-baz

        # If set, requires that a run be using a particular run phase. For
        # example, this could allow a particular run to only be used for
        # planning. Valid values: empty, `plan`, or `apply`.
        run_phase: ''

Spacelift: spacelift#

이 합류 방법은 Spacelift를 사용하여 인증하는 데 사용됩니다. 일반적으로 Spacelift에서 Teleport Terraform 공급자(자체 호스팅 배포 포함)에 의해 사용됩니다.

kind: token
version: v2
metadata:
  name: spacelift
spec:
  roles: [Bot]
  join_method: spacelift

  # This must match a bot name, created either with `tctl bots add` or by
  # creating a `bot` resource.
  bot_name: spacelift

  spacelift:
    # hostname should be the hostname of your Spacelift tenant.
    hostname: example.app.spacelift.io
    # enable_glob_matching enables glob-style matching for the allow rules.
    enable_glob_matching: true
    # allow specifies rules that control which Spacelift executions will be
    # granted access. Those not matching any allow rule will be denied.
    allow:
      # space_id identifies the space that the module or stack resides within.
      #
      # This field supports glob-style matching when the enable_glob_matching field is true:
      # - Use '*' to match zero or more characters.
      # - Use '?' to match any single character.
    - space_id: root
      # caller_type is the type of caller_id. This must be `stack` or `module`.
      caller_type: stack
      # caller_id is the id of the caller. e.g the name of the stack or module.
      #
      # This field supports glob-style matching when the enable_glob_matching field is true:
      # - Use '*' to match zero or more characters.
      # - Use '?' to match any single character.
      caller_id: my-stack
      # scope is the scope of the token - either `read` or `write`.
      # See https://docs.spacelift.io/integrations/cloud-providers/oidc/#about-scopes
      scope: read

Bitbucket Pipelines: bitbucket#

이 합류 방법은 Bitbucket의 OpenID Connect 지원을 사용하여 인증하는 데 사용되며, 일반적으로 머신 및 워크로드 아이덴티티의 tbot 또는 Teleport Terraform 공급자가 공유 시크릿 없이 Teleport에 인증할 수 있도록 하는 데 사용됩니다.

kind: token
version: v2
metadata:
  name: example-bot
spec:
  roles: [Bot]
  join_method: bitbucket
  bot_name: example
  bitbucket:
    # The URL of the workspace-specific OIDC identity provider. This can be
    # found in the repository settings under "Pipelines" and "OpenID Connect".
    identity_provider_url: $IDENTITY_PROVIDER_URL

    # The audience of the OIDC tokens issued by Bitbucket. This can be found in
    # the repository settings under "Pipelines" and "OpenID Connect".
    audience: $AUDIENCE

    # allow specifies the rules by which the Auth Service determines if `tbot`
    # should be allowed to join. All parameters in a given allow entry must
    # match for the join attempt to succeed, but many allow rules may be
    # provided. One or both of `workspace_uuid` and `repository_uuid` are
    # required; all other fields are optional.
    allow:
      - # The UUID of a workspace whose runs should be allowed to connect. This
        # value can be found in the repository settings under "Pipelines" and
        # "OpenID Connect". It must be enclosed in braces, i.e. `{...}`. At
        # least `workspace_uuid` or `repository_uuid` must be provided.
        workspace_uuid: '{WORKSPACE_UUID}'

        # The UUID of a repository whose runs should be allowed to connect. This
        # value can be found in the repository settings under "Pipelines" and
        # "OpenID Connect". It must be enclosed in braces, i.e. `{...}`. At
        # least `workspace_uuid` or `repository_uuid` must be provided.
        repository_uuid: '{REPOSITORY_UUID}'

        # If set, only steps tagged with the deployment environment linked to
        # this UUID will be allowed to connect. This value can be found in the
        # repository settings under "Pipelines" and "OpenID Connect" when a
        # deployment environment is selected from the drop-down menu. It must be
        # enclosed in braces, i.e. `{...}`. Optional.
        deployment_environment_uuid: '{DEPLOYMENT_ENVIRONMENT_UUID}'

        # If set, only workflows running on the named branch will be allowed to
        # connect. Optional.
        branch_name: "main"

Oracle Cloud: oracle#

Oracle 합류 방법은 Oracle Cloud Compute 인스턴스에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다.

# token.yaml
kind: token
version: v2
metadata:
  # The token name is not a secret because instances must prove that they are
  # running in your Oracle tenant to use this token.
  name: oracle-token
spec:
  # Use the minimal set of roles required (e.g. Node, Proxy, App, Kube, DB, WindowsDesktop).
  roles: [Node]

  # Set the join method allowed for this token.
  join_method: oracle

  oracle:
    allow:
      # OCID of the tenancy to allow instances to join from. Required.
      - tenancy: "ocid1.tenancy.oc1..<unique_ID>"
        # (Optional) OCIDs of compartments to allow instances to join from. Only the direct parent
        # compartment applies; i.e. nested compartments are not taken into account.
        # If empty, instances can join from any compartment in the tenancy.
        parent_compartments: ["ocid1.compartment.oc1..<unique_ID>"]
        # (Optional) Regions to allow instances to join from. Both full names ("us-phoenix-1")
        # and abbreviations ("phx") are allowed. If empty, instances can join from any region.
        regions: ["example-region"]
        # (Optional) OCIDs of specific compute instances that should be allowed to join.
        # If empty, any instance matching the other fields is allowed.
        # The instances field is supported in Teleport v18.4.0+.
        instances: ["ocid1.instance.oc1.<region>.<unique_ID>"]

합류 방법 및 토큰

원문 보기
요약

이 가이드는 Teleport 합류 프로세스의 핵심 개념을 설명하고, 지원되는 모든 합류 방법을 참조하며 보안 속성에 따라 분류합니다. 이 페이지를 읽기 전에 Teleport 핵심 개념에 익숙해야 합니다. Teleport 클러스터에 합류하는 것은 새 Teleport 인스턴스와 Teleport 클러스터에 이미 속해 있는 모든 기존 인스턴스 간의 신뢰를 확립하는 행위입니다.

이 가이드는 Teleport 합류 프로세스의 핵심 개념을 설명하고, 지원되는 모든 합류 방법을 참조하며 보안 속성에 따라 분류합니다. 이 가이드는 각 합류 방법으로 인스턴스를 합류시키는 방법을 단계별로 설명하지 않지만, 가능한 경우 관련 방법 가이드 링크를 제공합니다.

Prerequisite

이 페이지를 읽기 전에 Teleport 핵심 개념에 익숙해야 합니다.

정의#

합류#

Teleport 클러스터에 합류하는 것은 새 Teleport 인스턴스와 Teleport 클러스터에 이미 속해 있는 모든 기존 인스턴스 간의 신뢰를 확립하는 행위입니다. 합류 프로세스가 끝나면 Auth Service가 합류 인스턴스에 대한 인증서에 서명합니다. 해당 인증서는 확립된 신뢰를 나타냅니다. 이를 통해 새로 합류한 인스턴스가 다른 Teleport 인스턴스와 상호 작용할 수 있습니다.

인증서를 요청하려면 인스턴스가 Auth Service에 자신의 신원을 증명해야 합니다. Teleport는 합류 인스턴스가 자신의 진위성을 증명하는 여러 가지 방법을 제공하는데, 이를 합류 방법이라고 합니다.

합류 프로세스는 Teleport 서비스에 유효한 인증서가 없을 때만 발생합니다. 토큰이 인증서로 교환되면 해당 인증서가 이후 모든 연결 시도에 사용됩니다. 대부분의 경우 이는 첫 번째 시작 시 발생합니다.

합류 방법#

합류 방법은 Auth Service가 Teleport 클러스터에 합류를 요청하는 인스턴스가 합법적인지 검증하는 방법입니다. 일부 합류 방법은 범용적인 반면, 다른 방법은 합류 인스턴스의 컨텍스트에 의존합니다. 예를 들어 클라우드 공급자 합류 방법(예: iam, gcp 또는 azure) 또는 CI 공급자(예: github, gitlab, circleci)는 더 유연하고 더 나은 보안 보장을 제공하지만 특정 클라우드 공급자에서 실행되는 합류 인스턴스가 필요합니다.

다른 합류 방법은 다른 보안 보장을 제공할 수 있습니다. 예를 들어 일부 합류 방법은 합류 인스턴스가 갱신 가능한 인증서를 요청하도록 허용하는 반면, 다른 방법은 인스턴스가 인증서를 갱신하기 위해 다시 합류해야 합니다.

합류 방법과 해당 매개변수는 토큰 리소스에 지정됩니다.

토큰#

토큰은 어떤 합류 방법이 어떤 컨텍스트에서 사용될 수 있는지를 지정하는 Teleport 리소스입니다. 예를 들어, 토큰은 SSH 서비스가 AWS 계정 333333333333에 있고 역할 teleport-instance-role을 가정할 수 있는 경우 iam 합류 방법으로 합류할 수 있도록 허용할 수 있습니다:

kind: token
version: v2
metadata:
  name: my-iam-token
spec:
  roles: [Node]
  join_method: iam
  allow:
  - aws_account: "333333333333"
    aws_arn: "arn:aws:sts::333333333333:assumed-role/teleport-instance-role/i-*"
Warning

토큰 이름은 합류 방법에 따라 민감하거나 그렇지 않을 수 있습니다. 시크릿 기반 합류 방법은 토큰 이름이 비밀이어야 합니다. 이러한 경우 토큰 이름을 아는 것만으로도 인스턴스가 클러스터에 합류할 수 있으므로 토큰 이름을 보호해야 합니다.

합류 방법 분류#

시크릿 기반 vs 위임 기반#

시크릿 기반 합류 방법#

시크릿 기반 합류 방법은 범용적입니다: Teleport 서비스는 실행되는 플랫폼/클라우드 공급자에 관계없이 시크릿 기반 합류 방법을 사용할 수 있습니다. 합류 인스턴스는 시크릿을 전송하고 Auth Service는 그것이 알고 있는 것과 일치하는지 검증합니다. 이러한 합류 방법은 본질적으로 시크릿 유출에 취약하며, 가능한 경우 위임 합류 방법을 선호해야 합니다. 시크릿 기반 합류 방법을 사용해야 하는 경우, 토큰 유출 위험을 줄이기 위해 단기 토큰(예: 1시간만 유효)을 사용하는 것이 좋습니다.

시크릿 기반 합류 방법:

Warning

Teleport는 하위 호환성을 위해 정적 토큰을 지원하지만, 사용을 피해야 합니다.

위임 합류 방법#

위임 합류 방법은 합류 인스턴스의 컨텍스트와 제3자를 통해 신뢰를 확립합니다. 제3자는 클라우드 공급자, CI 플랫폼 또는 컨테이너 런타임일 수 있습니다. 이러한 방법은 모든 인스턴스에 사용할 수 없지만(예: Raspberry Pi에서 SSH 에이전트 합류는 불가능), 가능한 경우 선호해야 합니다.

위임 합류 방법은 더 세분화된 제어를 제공할 수도 있습니다. 예를 들어, 클라우드 공급자 기반 합류 방법은 가용성 영역, 서비스 계정 또는 클라우드 계정 ID에 따라 인스턴스의 합류를 허용할 수 있습니다.

위임 합류 방법:

갱신 가능 vs 갱신 불가능#

사용된 합류 방법에 따라 Auth Service는 갱신 가능하거나 갱신 불가능한 인증서를 발급할 수 있습니다.

인증서가 만료되려고 할 때, 갱신 가능한 인증서를 가진 인스턴스는 토큰을 다시 사용하지 않고도 새 인증서를 요청할 수 있습니다. 일반적으로 시크릿 기반 합류 방법은 시크릿 토큰이 민감하고 일반적으로 단기이기 때문에 갱신 가능한 인증서를 제공합니다. 단일 합류로 인스턴스는 무기한으로 클러스터의 일부로 남아 있을 수 있습니다.

갱신 가능한 합류 방법:

갱신 불가능한 인증서를 가진 노드는 만료 전에 새 인증서를 얻기 위해 다시 합류해야 합니다. 인스턴스는 자신이 합법적임을 다시 증명해야 합니다. 갱신 불가능한 합류 방법은 인스턴스 인증서를 훔친 공격자가 Teleport 클러스터에 대한 접근을 유지할 수 없음을 보장합니다. 이러한 합류 방법은 CI/CD 파이프라인이나 컨테이너화된 환경과 같은 임시 워크로드에 더 안전하고 더 적합한 것으로 간주될 수 있습니다.

갱신 불가능한 합류 방법:

토큰 리소스 레퍼런스#

토큰 리소스에는 모든 합류 방법에 대한 다음과 같은 공통 필드가 있습니다:

# token.yaml
kind: token
version: v2
metadata:
  name: my-token-name
spec:
  # 시스템 역할은 합류하는 Teleport 인스턴스가 실행할 수 있는 서비스를 설명합니다.
  # 이러한 역할은 인스턴스 인증서에 기록됩니다. 변경하려면(예: SSH 노드에 애플리케이션 접근 추가):
  # - 토큰을 편집하여 역할 업데이트(예: "App" 추가)
  # - Teleport 인스턴스 등록 해제
  # - 새 서비스를 활성화하도록 설정 수정(여기서는 "app_service.enabled")
  # - 인스턴스를 다시 합류시킴
  #
  # 필요한 최소 시스템 역할 세트를 사용해야 합니다.
  # 일반적인 역할:
  # - SSH 서비스를 위한 "Node"
  # - Proxy 서비스를 위한 "Proxy"
  # - Kubernetes 서비스를 위한 "Kube"
  # - Application 서비스를 위한 "App"
  # - Database 서비스를 위한 "Db"
  # - Windows Desktop 서비스를 위한 "WindowsDesktop"
  # - Discovery 서비스를 위한 "Discovery"
  # - 머신 및 워크로드 아이덴티티를 위한 "Bot"(설정 시 토큰에 "spec.bot_name"을 설정해야 함)
  # - Jamf 서비스를 위한 "MDM"
  roles:
    - Node
    - App
  join_method: gcp
  # 머신 및 워크로드 아이덴티티에 토큰이 사용되는 경우에만 봇 이름을 설정합니다.
  # 설정 시 토큰에 "Bot" 역할도 있어야 합니다.
  bot_name: my-bot
  # SuggestedLabels는 이 토큰을 사용하여 클러스터에 등록할 때 리소스가 설정해야 하는 레이블 세트입니다.
  # 현재 node-join 스크립트만 제안에 따라 설정을 생성합니다.
  suggested_labels:
    teams: ["sales-eng", "eng", "qa"]
    application: ["demo-product"]
  # SuggestedAgentMatcherLabels는 디스커버리 에이전트가 리소스를 매칭하는 데 사용할 레이블 세트입니다.
  # 에이전트가 이 토큰을 사용할 때 에이전트는 이러한 레이블과 일치하는 리소스를 모니터링해야 합니다.
  # 데이터베이스의 경우, 이는 `db_service.resources.labels`에 레이블을 추가하는 것을 의미합니다.
  # 현재 node-join 스크립트만 제안에 따라 설정을 생성합니다.
  suggested_agent_matcher_labels:
    teams: ["sales-eng"]

합류 방법#

정적 토큰#

Warning

이 합류 방법은 장기 토큰이 도난당하고 재사용될 수 있어 본질적으로 덜 안전합니다. 이에 의존하면 Teleport 사용의 보안 이점이 크게 감소합니다. 사용을 강력히 권장하지 않습니다. 대신 일시적 토큰을 사용해야 합니다.

정적 토큰은 Auth Service 설정(teleport.yaml)에 정의된 토큰입니다. 토큰 이름은 비밀로 유지해야 합니다. 이를 알면 Teleport 클러스터에 인스턴스를 합류시킬 수 있습니다.

auth_service:
    enabled: true
    # 클러스터에 새 인스턴스를 추가하기 위해 미리 정의된 토큰. 각 토큰은
    # 새 노드가 가정할 수 있는 역할을 지정합니다. 더 안전한 방법으로
    # 인스턴스를 추가하려면 `tctl nodes add --ttl` 명령을 사용하여 자동 만료
    # 토큰을 생성합니다.
    #
    # `pwgen`과 같은 도구를 사용하여 32바이트 이상의 충분히 무작위인
    # 토큰을 생성하는 것이 좋습니다.
    tokens:
        - "proxy,node:xxxxx"
        - "auth:yyyy"
        - "discovery,app,db:zzzzz"

일시적 토큰#

일시적 토큰은 CLI 또는 Teleport API를 통해 동적으로 생성되는 시크릿 토큰입니다. 시간 제한이 있으며 일반적으로 인스턴스를 Teleport 클러스터에 합류시키기 직전에 생성됩니다.

CLI로 생성할 수 있습니다(지정하지 않으면 강력한 무작위 값이 선택되고, 기본 TTL은 30분):

$ tctl tokens add --type discovery,app --ttl 15m

또는 Teleport 리소스로:

kind: token
version: v2
metadata:
  expires: "2023-11-24T21:45:40.104524Z"
  name: (=presets.tokens.first=)
spec:
  join_method: token
  roles:
    - Discovery
    - App

머신 및 워크로드 아이덴티티 봇이 일시적 합류 토큰을 사용하면 토큰이 삭제됩니다.

Upgrade to Bound Keypair

새 봇 배포는 bound_keypair 합류 방법으로 업그레이드를 고려해야 합니다.

Bound Keypair: bound_keypair#

Bound Keypair 토큰은 보안과 유연성을 향상시키는 시크릿 기반 합류 방법의 대안입니다. 영구 스토리지가 있는 플랫폼에서 가장 잘 사용되지만, 시크릿을 영구적으로 저장할 수 있는 모든 환경에서 사용할 수 있습니다.

이 합류 방법은 TPM이 없는 온프렘 환경이나 특화된 위임 합류 방법이 없는 클라우드 플랫폼에 권장됩니다.

bound_keypair는 인증서가 자주 갱신되는 Machine & Workload ID 봇을 위해 설계되었으며 가장 적합하지만, 장기 인증서가 발급되는 표준 Teleport 에이전트 합류(Teleport v18.8부터 지원)에도 사용할 수 있습니다. 에이전트에 대한 Bound Keypair는 사용 전에 확인해야 할 특정 제한사항이 있습니다.

kind: token
version: v2
metadata:
  name: example-token
spec:
  roles: [Bot]
  join_method: bound_keypair
  bot_name: example

  # Fields related to the bound keypair joining process.
  bound_keypair:
    # Fields related to the initial join attempt.
    onboarding:
      # If set to a public key in SSH authorized_keys format, the
      # joining client must have the corresponding private key to join. This
      # keypair may be created using `tbot keypair create`. If set,
      # `registration_secret` and `must_register_before` are ignored.
      initial_public_key: ""

      # If set to a secret string value, a client may use this secret to perform
      # the first join without pre-registering a public key in
      # `initial_public_key`. If unset and no `initial_public_key` is provided,
      # a random value will be generated automatically into
      # `.status.bound_keypair.registration_secret`.
      registration_secret: ""

      # If set to an RFC 3339 timestamp, attempts to register via
      # `registration_secret` will be denied once the timestamp has elapsed. If
      # more time is needed, this field can be edited to extend the registration
      # period.
      must_register_before: ""

    # Fields related to recovery after certificates have expired.
    recovery:
      # The maximum number of allowed recovery attempts. This value may
      # be raised or lowered after creation to allow additional recovery
      # attempts should the initial limit be exhausted. If `mode` is set to
      # `standard`, recovery attempts will only be allowed if
      # `.status.bound_keypair.recovery_count` is less than this limit. This
      # limit is not enforced if `mode` is set to `relaxed` or `insecure`. This
      # value must be at least 1 to allow for the initial join during
      # onboarding, which counts as a recovery.
      limit: 1

      # The recovery rule enforcement mode. Valid values:
      # - standard (or unset): all configured rules enforced. The recovery limit
      #   and client join state are required and verified. This is the most
      #   secure recovery mode.
      # - relaxed: recovery limit is not enforced, but client join state is
      #   still required. This effectively allows unlimited recovery attempts,
      #   but client join state still helps mitigate stolen credentials.
      # - insecure: neither the recovery limit nor client join state are
      #   enforced. This allows any client with the private key to join freely.
      #   This is less secure, but can be useful in certain situations, like in
      #   otherwise unsupported CI/CD providers. This mode should be used with
      #   care, and RBAC rules should be configured to heavily restrict which
      #   resources this identity can access.
      mode: "standard"

    # If set to an RFC 3339 timestamp, once elapsed, a keypair rotation will be
    # forced on next join if it has not already been rotated. The most recent
    # rotation is recorded in `.status.bound_keypair.last_rotated_at`.
    rotate_after: ""

AWS IAM 역할: iam#

IAM 합류 방법은 EC2 인스턴스에 연결된 IAM 역할과 같이 IAM 자격 증명에 접근할 수 있는 곳에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. 특정 권한이나 IAM 정책은 필요하지 않습니다: 정책이 연결되지 않은 IAM 역할로 충분합니다. Teleport Auth Service에는 IAM 자격 증명이 필요하지 않습니다.

이는 AWS에서 실행되는 워크로드에 합류하는 데 권장되는 방법입니다.

  # token.yaml
  kind: token
  version: v2
  metadata:
    # the token name is not a secret because instances must prove that they are
    # running in your AWS account to use this token
    name: iam-token
  spec:
    # use the minimal set of roles required (e.g. Node, App, Kube, DB, WindowsDesktop)
    roles: [Node]
    
    # set the join method allowed for this token
    join_method: iam
    
    allow:
      # specify the AWS account which Teleport processes may join from
      - aws_account: "111111111111"
      # multiple allow rules are supported
      - aws_account: "222222222222"
      # aws_arn is optional and allows you to restrict the IAM role of joining
      # Teleport processes
      - aws_account: "333333333333"
        aws_arn: "arn:aws:sts::333333333333:assumed-role/teleport-node-role/i-*"
    ```
<!-- /INCLUDE:ENGLISH -->

<div class="admonition note"><div class="admonition-title">See Also</div>

- [AWS IAM 역할을 통한 서비스 합류하기](../../installation/agents/aws-iam.mdx).
- [AWS에서 머신  워크로드 아이덴티티 배포하기](../../machine-workload-identity/deployment/aws.mdx)

</div>

### AWS EC2 신원 문서: `ec2`

EC2 합류 방법은 EC2 인스턴스에서 실행되는 모든 Teleport 프로세스에서 사용할  있습니다. EC2 인스턴스당 하나의 Teleport 프로세스만 EC2 합류 방법을 사용할  있습니다.

Teleport Auth Service에는 `ec2:DescribeInstances` 권한이 있는 IAM 자격 증명이 필요합니다. 클러스터에 합류하는 Teleport 프로세스에는 IAM 자격 증명이 필요하지 않습니다.

<div class="admonition warning"><div class="admonition-title">Warning</div>

EC2 합류 방법은 Teleport Enterprise Cloud  Teleport Team에서 사용할  없습니다. Teleport Enterprise Cloud  Team 고객은 [IAM 합류 방법](#aws-iam-role-iam) 또는 [일시적 시크릿 토큰](#ephemeral-tokens)을 사용할  있습니다.

</div>

<!-- INCLUDE:ENGLISH:docs/pages/includes/provision-token/ec2-spec.mdx -->
```yaml
# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your AWS account to use this token
  name: ec2-token
spec:
  # use the minimal set of roles required (e.g. Node, App, Kube, DB, WindowsDesktop)
  roles: [Node]

  # set the join method allowed for this token
  join_method: ec2

  # aws_iid_ttl is the amount of time after the EC2 instance is launched during
  # which it should be allowed to join the cluster. Use a short TTL to decrease
  # the risk of stolen EC2 Instance Identity Documents being used to join your
  # cluster.
  #
  # When launching your first Teleport process using the EC2 join method, you may need to
  # temporarily configure a higher `aws_iid_ttl` value so that you have time
  # to get Teleport set up and configured. This feature works best once Teleport
  # is configured in an EC2 AMI to start automatically on launch.
  aws_iid_ttl: 5m

  allow:
  - aws_account: "111111111111" # your AWS account ID
    aws_regions: # use the minimal set of AWS regions required
    - us-west-1
    - us-west-2

Azure 관리 신원: azure#

Azure 합류 방법은 Azure Virtual Machine에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다.

# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your Azure subscription to use this token
  name: azure-token
spec:
  # use the minimal set of roles required
  roles: [Node]
  join_method: azure
  azure:
    allow:
      # specify the Azure subscription which Teleport processes may join from
      - subscription: 11111111-1111-1111-1111-111111111111
      # multiple allow rules are supported
      - subscription: 22222222-2222-2222-2222-222222222222
      # resource_groups is optional and allows you to restrict the resource group of
      # joining Teleport processes
      - subscription: 33333333-3333-3333-3333-333333333333
        resource_groups: ["group1", "group2"]

Azure Devops: azure_devops#

Azure DevOps는 Azure DevOps 파이프라인에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. 이 합류 방법은 일반적으로 장기 시크릿 없이 Azure DevOps 파이프라인에서 Teleport 보호 리소스에 접근하기 위해 머신 및 워크로드 아이덴티티와 함께 사용됩니다.

# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your Azure DevOps organization to use this token
  name: azure-devops-token
spec:
  roles: [Bot]
  join_method: azure_devops
  bot_name: my-bot
  azure_devops:
    # the UUID of the Azure DevOps organization that the pipeline will be
    # joining from. Joins from pipelines in other organizations will be
    # rejected.
    organization_id: 11111111-1111-1111-1111-111111111111
    # a list of rules that determine which Azure DevOps pipelines can use this
    # token to join. At least one must be specified, and each rule must define
    # at least the `sub`, `project_name` or `project_id` field.
    allow:
        # the `sub` field is a unique identifier for the pipeline in Azure DevOps.
        # It is a combination of the organization, project, and pipeline name.
        # The format is `p://<organization>/<project>/<pipeline>`.
      - sub: p://my-organization/my-project/my-pipeline
        # the `project_name` field is the name of the Azure DevOps project the
        # pipeline is in.
        project_name: my-project
        # the `pipeline_name` field is the name of the Azure DevOps pipeline.
        pipeline_name: my-pipeline
        # the `project_id` field is the unique identifier for the Azure DevOps
        # project the pipeline is in.
        project_id: 22222222-2222-2222-2222-222222222222
        # the `definition_id` is the unique identifier for the pipeline
        # definition within the Azure DevOps project.
        definition_id: 1
        # the `repository_uri` is the URI of the source code repository that
        # the pipeline is running against.
        repository_uri: https://github.com/gravitational/teleport.git
        # the `repository_version` is the commit SHA of the source code that
        # the pipeline is running against.
        repository_version: e6b9eb29a288b27a3a82cc19c48b9d94b80aff36
        # the `repository_ref` is the branch or tag of the source code that
        # the pipeline is running against.
        repository_ref: refs/heads/main

Env0: env0#

Env0 합류 방법은 Env0 클라우드 환경에서 실행되는 워크로드에서 사용할 수 있습니다. 토큰이 러너 환경에 발급되려면 "Enable OIDC during deployments" 옵션을 활성화해야 합니다.

이 합류 방법은 일반적으로 Teleport Terraform 공급자가 Env0 클라우드 환경에서 Teleport에 인증하는 데 사용됩니다. 다른 플랫폼에서 Terraform 실행에 합류하는 데는 사용할 수 없으며 대신 전용 합류 방법을 사용해야 합니다.

env0 합류 방법은 Teleport v18.4.0 이상이 필요합니다.

kind: token
version: v2
metadata:
  name: env0
spec:
  roles: [Bot]
  join_method: env0

  # This must match a bot name, created either with `tctl bots add` or by
  # creating a `bot` resource.
  bot_name: env0

  env0:
    allow:
      # organization_id and one of either project_name or project_id must be
      # set. All other fields are optional and only checked if set.
      # For more information on possible values, see Env0's documentation:
      # https://docs.envzero.com/guides/integrations/oidc-integrations#format-of-the-openid-connect-id-token
      - organization_id: "00000000-0000-0000-0000-000000000000"

        # A unique project identifier. Either this field or `project_name` must
        # be set.
        project_id: "00000000-0000-0000-0000-000000000000"

        # The project name. Either this field or `project_id` must be set.
        project_name: ExampleProject

        # A unique template identifier.
        template_id: "00000000-0000-0000-0000-000000000000"

        # The template name, optional.
        template_name: ExampleTemplate

        # The unique environment ID.
        environment_id: "00000000-0000-0000-0000-000000000000"

        # The environment name.
        environment_name: ExampleEnvironment

        # The workspace name.
        workspace_name: WorkspaceName

        # The deployment type, including "deploy", "destroy", "prPlan", "task"
        deployment_type: ""

        # The email address of the user that started the deployment.
        deployer_email: ""

        # A custom value provided via the `ENV0_OIDC_TAG` environment variable
        env0_tag: ""

GCP 서비스 계정: gcp#

GCP 합류 방법은 GCP VM에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. VM에는 서비스 계정이 할당되어 있어야 합니다(기본 서비스 계정도 괜찮습니다). 클러스터에 합류하는 Teleport 프로세스에는 IAM 역할이 필요하지 않습니다.

# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your GCP project to use this token
  name: gcp-token
spec:
  # use the minimal set of roles required (e.g. Node, Proxy, App, Kube, DB, WindowsDesktop)
  roles: [Node]

  # set the join method allowed for this token
  join_method: gcp

  gcp:
    allow:
      # The GCP project ID(s) that VMs can join from.
      - project_ids: ["example-project-id"]
        # (Optional) The locations that VMs can join from. Note: both regions and
        # zones are accepted.
        locations: ["us-west1", "us-west2-a"]
        # (Optional) The email addresses of service accounts that VMs can join
        # with.
        service_accounts: ["example@example.com"]

GitHub Actions: github#

Teleport는 GitHub 호스팅 및 자체 호스팅 GitHub Actions 러너와 GitHub Enterprise Server 모두에서 안전한 합류를 지원합니다. 이 합류 방법은 일반적으로 GitHub Actions 파이프라인에서 Teleport 보호 리소스에 접근하기 위해 머신 및 워크로드 아이덴티티와 함께 사용됩니다.

kind: token
version: v2
metadata:
  # name identifies the token. When configuring a bot or node to join using this
  # token, this name should be specified.
  name: github-token
spec:
  # For Machine & Workload Identity via GitHub joining, roles will always be
  # "Bot" and  join_method will always be "github".
  roles: [Bot]
  join_method: github

  # bot_name specifies the name of the bot that this token will grant access to
  # when it is used.
  bot_name: github-demo

  github:
    # enterprise_server_host allows joining from GitHub Actions workflows in a
    # GitHub Enterprise Server instance. For normal situations, where you are
    # using github.com, this option should be omitted. If you are using GHES,
    # this value should be configured to the hostname of your GHES instance.
    enterprise_server_host: ghes.example.com

    # static_jwks allows the JSON Web Key Set (JWKS) used to verify the token
    # issued by GitHub Actions to be overridden. This can be used in scenarios
    # where the Teleport Auth Service is unable to reach a GHES server.
    #
    # This field is optional and should only be used with GitHub Enterprise
    # Server. When unspecified, the JWKS will be fetched automatically using the
    # GHES server specified in `enterprise_server_host`.
    static_jwks: |
      {"keys":[--snip--]}

    # enterprise_slug allows the slug of a GitHub Enterprise organisation to be
    # included in the expected issuer of the OIDC tokens. This is for
    # compatibility with the include_enterprise_slug option in GHE.
    #
    # This field should be set to the slug of your Github Enterprise organization if this is enabled. If
    # this is not enabled, then this field must be left empty. This field cannot
    # be specified if `enterprise_server_host` is specified.
    #
    # See https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#customizing-the-issuer-value-for-an-enterprise
    # for more information about customized issuer values.
    enterprise_slug: slug

    # allow is an array of rule configurations for what GitHub Actions workflows
    # should be allowed to join. All options configured within one allow entry
    # must be satisfied for the GitHub Actions run to be allowed to join. Where
    # multiple allow entries are specified, any run which satisfies all of the
    # options within a single entry will be allowed to join.
    #
    # An allow entry must include at least one of:
    # - repository
    # - repository_owner
    # - sub
    allow:
      - # repository is a fully qualified (e.g. including the owner) name of a
        # GitHub repository.
        repository: gravitational/teleport
        # repository_owner is the name of an organization or user that a
        # repository belongs to.
        repository_owner: gravitational
        # workflow is the exact name of a workflow as configured in the GitHub 
        # Action workflow YAML file.
        workflow: my-workflow
        # environment is the environment associated with the GitHub Actions run.
        # If no environment is configured for the GitHub Actions run, this will
        # be empty.
        environment: production
        # actor is the GitHub username that caused the GitHub Actions run,
        # whether by committing or by directly despatching the workflow.
        actor: octocat
        # ref is the git ref that triggered the action run.
        ref: refs/heads/main
        # ref_type is the type of the git ref that triggered the action run.
        ref_type: branch
        # sub is a concatenated string of various attributes of the workflow 
        # run. GitHub explains the format of this string at:
        # https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims
        sub: repo:gravitational/example-repo:environment:production

GitHub Actions 헬퍼#

Teleport 머신 및 워크로드 아이덴티티와 GitHub Actions를 활용할 때 워크플로에서 사용할 수 있는 일련의 기성품 GitHub Actions를 제공합니다.

이러한 개별 액션에 대한 자세한 내용은 GitHub 저장소에서 확인할 수 있습니다:

이러한 액션을 사용하는 데 문제가 있으면 소스 저장소에서 이슈를 제기하십시오: https://github.com/teleport-actions/root.

CircleCI: circleci#

이 합류 방법은 일반적으로 Circle CI 파이프라인에서 Teleport 보호 리소스에 접근하기 위해 머신 및 워크로드 아이덴티티와 함께 사용됩니다.

kind: token
version: v2
metadata:
  name: example-bot
spec:
  roles: [Bot]
  join_method: circleci
  bot_name: example
  circleci:
    organization_id: $ORGANIZATION_ID
    # allow specifies the rules by which the Auth Service determines if `tbot`
    # should be allowed to join.
    allow:
      - # CircleCI context id. See the CircleCI Machine & Workload Identity
        # guide to learn how to create a context and recover its ID.
        context_id: 00000000-0000-0000-0000-000000000000
        # CircleCI projectID.
        project_id: 1234

GitLab: gitlab#

Teleport는 클라우드 호스팅 및 자체 호스팅 GitLab 인스턴스 모두에서 안전한 합류를 지원합니다. 최소 지원 GitLab 버전은 15.7입니다.

이 합류 방법은 일반적으로 Gitlab CI 파이프라인에서 Teleport 보호 리소스에 접근하기 위해 머신 및 워크로드 아이덴티티와 함께 사용됩니다.

kind: token
version: v2
metadata:
  # name identifies the token. When configuring a bot or node to join using this
  # token, this name should be specified.
  name: gitlab-demo
spec:
  # The Bot role indicates that this token grants access to a bot user, rather
  # than allowing a node to join.
  roles: [Bot]
  # join_method for GitLab joining will always be "gitlab".
  join_method: gitlab

  # bot_name specifies the name of the bot that this token will grant access to
  # when it is used.
  bot_name: gitlab-demo

  gitlab:
    # domain should be the domain of your GitLab instance. If you are using
    # GitLab's cloud hosted offering, omit this field entirely.
    domain: gitlab.example.com
    # static_jwks allows the JSON Web Key Set (JWKS) used to verify the token
    # issued by GitLab to be overridden. This can be used in scenarios
    # where the Teleport Auth Service is unable to reach a GitLab server.
    #
    # This field is optional. When unspecified, the JWKS will be fetched
    # automatically using the value from the domain field and OIDC.
    static_jwks: |
      {"keys":[--snip--]}
    # allow is an array of rule configurations for what GitLab CI jobs should be
    # allowed to join. All options configured within one allow entry
    # must be satisfied for the GitLab CI run to be allowed to join. Where
    # multiple allow entries are specified, any job which satisfies all of the
    # options within a single entry will be allowed to join.
    #
    # An allow entry must include at least one of:
    # - project_path
    # - namespace_path
    # - sub
    # This ensures that GitLab CI runs in other GitLab user's projects are not
    # able to access your Teleport cluster.
    allow:
      # project_path restricts joins to jobs that originate within the
      # specified project.
      #
      # This field supports glob-style matching:
      # - Use '*' to match zero or more characters.
      # - Use '?' to match any single character.
      - project_path: my-user/my-project
        # namespace_path restricts joins to any run within project that exists
        # within the specified namespace. A namespace will either be a username
        # or the name of a group.
        #
        # This field supports glob-style matching:
        # - Use '*' to match zero or more characters.
        # - Use '?' to match any single character.
        namespace_path: my-user
        # pipeline_source restricts joins to jobs triggered by certain criteria,
        # e.g triggered through the web interface.
        pipeline_source: web
        # environment restricts joins to jobs that are associated with the
        # specified environment
        environment: production
        # ref_type restricts joins to jobs that were triggered by a specific
        # type of git reference. Either `branch` or `tag`.
        ref_type: branch
        # ref restricts joins to jobs that were triggered by a specific git
        # reference. Combine this with `ref_type` to create allow rules that
        # can only be triggered by a specific branch or tag.
        #
        # This field supports glob-style matching:
        # - Use '*' to match zero or more characters.
        # - Use '?' to match any single character.
        ref: main
        # sub is a single string that concatenates the project_path, ref_type
        # and ref. This can be used to restrict joins using a single string,
        # whilst also describing a specific project and git ref.
        #
        # It is better to use the individual fields, as it is easy to mis-format
        # the sub string.
        #
        # This field supports glob-style matching:
        # - Use '*' to match zero or more characters.
        # - Use '?' to match any single character.
        sub: project_path:my-user/my-project:ref_type:branch:ref:main
        # user_login restricts joins to jobs that were triggered by a specific
        # username.
        user_login: octocat
        # user_email restricts joins to jobs that were triggered by a specific
        # user with the given email
        user_email: octo.cat@example.com
        # ref_protected if set to true restricts joins to jobs running against a
        # protected ref.
        # If omitted, the protection status of the ref is not checked.
        ref_protected: true
        # environment_protected if set to true restricts joins to jobs running
        # against a protected ref.
        # If omitted, the protection status of the ref is not checked.
        environment_protected: true
        # ci_config_sha restricts joins to jobs that are using a specific
        # commit of CI configuration.
        ci_config_sha: ffffffffffffffffffffffffffffffffffffffff
        # ci_config_ref_uri restricts joins to jobs that are using a specific
        # CI configuration source.
        ci_config_ref_uri: gitlab.example.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main
        # deployment_tier restricts joins to jobs that are deploying to a
        # specific deployment_tier.
        deployment_tier: production
        # project_visibility restricts joins to jobs that are running against a
        # project with a specific visibility configuration.
        project_visibility: public

Kubernetes: kubernetes#

Kubernetes 합류 방법은 세 가지 변형이 있습니다:

Kubernetes 인클러스터#

Kubernetes 인클러스터 합류는 Auth Service와 동일한 Kubernetes 클러스터에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. Kubernetes ServiceAccount 토큰을 사용하여 파드 신원을 검증합니다. 이 방법은 일반적으로 Kubernetes 클러스터 내에서만 접근할 수 있는 Kubernetes TokenReview API에 의존합니다. 이 제한으로 인해 이 합류 방법은 Kubernetes의 자체 호스팅 Teleport 클러스터에서만 사용할 수 있습니다.

파드가 Terminated 상태에 들어가면 토큰이 즉시 취소되므로 가능한 경우 이 방법을 선호해야 합니다.

# token.yaml
kind: token
version: v2
metadata:
  # The token name is not a secret as the Kubernetes join method relies on the
  # Kubernetes signature to establish trust and not on the join token name.
  name: kubernetes-token
  # set a long expiry time, the default for tokens is only 30 minutes
  expires: "2050-01-01T00:00:00Z"
spec:
  # Use the minimal set of system roles required.
  roles: [App]

  # set the join method allowed for this token
  join_method: kubernetes
  
  kubernetes:
    # If type is not specified, it defaults to in_cluster
    type: in_cluster
    allow:
      # Service account names follow the format "namespace:serviceaccountname".
      - service_account: "teleport-agent:teleport-app-service"

Kubernetes JWKS#

Kubernetes JWKS 합류는 Kubernetes에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다. Auth Service가 Kubernetes에서 실행될 필요가 없으므로 이 방법은 Teleport Cloud를 포함한 모든 Teleport 클러스터에서 사용할 수 있습니다. 이 합류 방법은 공개 Kubernetes 서명 키를 내보내고 이를 사용하여 Kubernetes SA 토큰 서명을 검증함으로써 작동합니다. 서명 검증은 Kubernetes에 접근하지 않고 Auth Service에서 수행할 수 있습니다.

kind: token
version: v2
metadata:
  name: example
spec:
  roles: [App]
  join_method: kubernetes
  kubernetes:
    # static_jwks configures the Auth Service to validate the JWT presented by
    # `tbot` using the public key from a statically configured JWKS.
    type: static_jwks
    static_jwks:
      jwks: |
        # Place the kubernetes JWKS here (`kubectl get --raw /openid/v1/jwks`)
        {"keys":[--snip--]}
    # allow specifies the rules by which the Auth Service determines if the node
    # should be allowed to join.
    allow:
      - service_account: "namespace:serviceaccount"
Warning

Kubernetes CA를 교체한 후 새 Kubernetes 서명 키를 포함하도록 Kubernetes JWKS 토큰을 업데이트해야 합니다(spec.kubernetes.static_jwks.jwks 필드 업데이트).

Kubernetes OIDC#

Kubernetes OIDC 합류는 클러스터가 공개적으로 접근 가능한 OIDC 호환 발급자에서 서비스 계정 토큰을 발급하는 Kubernetes에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다.

이 기능은 Kubernetes 1.21에서 추가된 Kubernetes 서비스 계정 발급자 디스커버리 기능을 사용하여 Kubernetes 워크로드를 검증합니다. Amazon EKS와 같은 일부 공급자는 OIDC 합류를 활성화하기 위해 추가 설정이 필요할 수 있습니다.

위에 설명된 static_jwks 변형과 달리, 이 방법은 업스트림 공급자에서 JWKS 키를 동적으로 가져오며 키가 교체되더라도 재설정이 필요하지 않습니다. EKS와 같은 공급자는 키를 자주 교체합니다. 그러나 모든 Kubernetes 구현에 접근 가능한 OIDC 엔드포인트가 있는 것은 아닙니다.

Supported Teleport Version

Kubernetes OIDC 합류를 사용하려면 Teleport 클러스터가 최소 버전 18.1.5를 실행해야 합니다.

kind: token
version: v2
metadata:
  name: example
spec:
  roles: [App]
  join_method: kubernetes
  kubernetes:
    # oidc configures the Auth Service to validate the JWT presented by `tbot`
    # using the public keys published by the configured OIDC issuer.
    type: oidc
    oidc:
      # Issuer must be a fully-qualified HTTPS URL and may vary between
      # providers.
      issuer: https://oidc.eks.us-west-2.amazonaws.com/id/my-cluster
    # allow specifies the rules by which the Auth Service determines if the node
    # should be allowed to join.
    allow:
      - service_account: "namespace:serviceaccount"

Trusted Platform Module: tpm#

The tpm join method is a secure way for Bots and Agents to authenticate with the Teleport Auth Service without using any shared secrets. Instead of using a shared secret, the unique identity of the host's Trusted Platform Module (TPM) and public key cryptography is used to authenticate the host.

In environments where there is no other form of identity available to machines, e.g on-prem, this is the most secure method for joining. It avoids the need to distribute a shared secret as is needed for the token join method.

A Trusted Platform Module (TPM) is a secure, physical cryptoprocessor that is installed on a host. TPMs can store cryptographic material and perform a number of cryptographic operations, without exposing the cryptographic material to the operating system. Each TPM has a unique key pair burned-in known as the Endorsement Key (EK). This key does not change, even if the host operating system is reinstalled.

Some TPMs also contain an X.509 certificate for this key pair that is signed by the manufacturer's CA. This is known as the EK Certificate (EKCert). This certificate can be used by the TPM to prove to a third-party (who trusts the manufacturer's CA) that the TPM is genuine and abides by the TPM specification.

When using the tpm join method, you must first query the TPM's public key and then create a join token that explicitly allows this public key. To list information about the detected TPM, run the teleport tpm identify command.

If you have a large number of hosts, it may make sense to use automation tooling such as Ansible to query the TPMs across your fleet and then generate join tokens.

kind: token
version: v2
metadata:
  # name identifies the token. When configuring a bot or node to join using this
  # token, this name should be specified.
  name: tpm-token
spec:
  # For Machine & Workload Identity via TPM joining, roles will always be "Bot"
  # and join_method will always be "tpm".
  roles: [Bot]
  join_method: tpm

  # bot_name specifies the name of the bot that this token will grant access to
  # when it is used.
  bot_name: tpm-demo

  # tpm specifies the TPM join method specific configuration for this token.
  tpm:
    # ekcert_allowed_cas is a list of CA certificates that will be used to
    # validate TPM EKCerts. These should be PEM wrapped.
    #
    # When specified, joining TPMs must present an EKCert signed by one of the
    # specified CAs. TPMs that do not present an EKCert will be not permitted to
    # join.
    #
    # When unspecified, TPMs will be allowed to join with either an EKCert or an
    # EKPubHash.
    ekcert_allowed_cas:
      - |
        -----BEGIN CERTIFICATE-----
        ... CA Certificate Data ...
        -----END CERTIFICATE-----
    # allow is a list of Rules, the presented TPM must match one allow rule to
    # be permitted to join using this token.
    allow:
        # description is a human-readable description of the rule. It has no
        # bearing on whether a TPM is allowed to join, but can be used to
        # associate a rule with a specific host (e.g the asset tag of the server
        # in which the TPM resides).
      - description: "example-build-server-100"
        # ek_public_hash is the SHA256 hash of the EKPub marshaled in PKIX format
        # and encoded in hexadecimal. This value will also be checked when a TPM
        # has submitted an EKCert, and the public key in the EKCert will be used
        # for this check.
        ek_public_hash: "d4b4example6fabfc568d74f2example6c35a05337d7af9a6example6c891aa6"
        # ek_certificate_serial is the serial number of the EKCert in hexadecimal
        # with colon separated nibbles. This value will not be checked when a TPM
        # does not have an EKCert configured.
        ek_certificate_serial: "01:23:45:67:89:ex:am:pl:e0:23:45:67:89:ab:cd:ef"

Terraform Cloud: terraform_cloud#

이 합류 방법은 Terraform Cloud 워크로드 신원을 사용하여 인증하는 데 사용됩니다. 일반적으로 HCP Terraform 또는 자체 호스팅 Terraform Enterprise에서 Teleport Terraform 공급자에 의해 사용됩니다. 다른 플랫폼에서 Terraform 실행에 합류하는 데는 사용할 수 없으며 대신 전용 합류 방법을 사용해야 합니다.

Enterprise

자체 호스팅 Terraform Enterprise 지원은 Teleport Enterprise가 필요합니다.

kind: token
version: v2
metadata:
  name: terraform
spec:
  roles: [Bot]
  join_method: terraform_cloud

  # This must match a bot name, created either with `tctl bots add` or by
  # creating a `bot` resource.
  bot_name: terraform

  terraform_cloud:
    # Manually override the expected audience. If unset, defaults to the
    # Teleport cluster name. It is not recommended to override this value.
    audience: ''

    # Specify the hostname of a Terraform Enterprise instance. Overriding this
    # value to use Terraform Enterprise requires Teleport Enterprise.
    # If unset, refers to the public `app.terraform.io` instance.
    hostname: ''

    allow:
      # At least one of `organization_name` or `organization_id` must be set.
      # Values are case and whitespace sensitive.
      - organization_name: OrgName
        organization_id: org-foo

        # At least one of `project_name`, `project_id`, `workspace_name`, or
        # `workspace_id` must also be set.
        project_name: ProjectName
        project_id: prj-bar

        # If no `workspace_name` or `workspace_id` are set, all workspaces
        # within the specified project will be allowed to join.
        workspace_name: WorkspaceName
        workspace_id: ws-baz

        # If set, requires that a run be using a particular run phase. For
        # example, this could allow a particular run to only be used for
        # planning. Valid values: empty, `plan`, or `apply`.
        run_phase: ''

Spacelift: spacelift#

이 합류 방법은 Spacelift를 사용하여 인증하는 데 사용됩니다. 일반적으로 Spacelift에서 Teleport Terraform 공급자(자체 호스팅 배포 포함)에 의해 사용됩니다.

kind: token
version: v2
metadata:
  name: spacelift
spec:
  roles: [Bot]
  join_method: spacelift

  # This must match a bot name, created either with `tctl bots add` or by
  # creating a `bot` resource.
  bot_name: spacelift

  spacelift:
    # hostname should be the hostname of your Spacelift tenant.
    hostname: example.app.spacelift.io
    # enable_glob_matching enables glob-style matching for the allow rules.
    enable_glob_matching: true
    # allow specifies rules that control which Spacelift executions will be
    # granted access. Those not matching any allow rule will be denied.
    allow:
      # space_id identifies the space that the module or stack resides within.
      #
      # This field supports glob-style matching when the enable_glob_matching field is true:
      # - Use '*' to match zero or more characters.
      # - Use '?' to match any single character.
    - space_id: root
      # caller_type is the type of caller_id. This must be `stack` or `module`.
      caller_type: stack
      # caller_id is the id of the caller. e.g the name of the stack or module.
      #
      # This field supports glob-style matching when the enable_glob_matching field is true:
      # - Use '*' to match zero or more characters.
      # - Use '?' to match any single character.
      caller_id: my-stack
      # scope is the scope of the token - either `read` or `write`.
      # See https://docs.spacelift.io/integrations/cloud-providers/oidc/#about-scopes
      scope: read

Bitbucket Pipelines: bitbucket#

이 합류 방법은 Bitbucket의 OpenID Connect 지원을 사용하여 인증하는 데 사용되며, 일반적으로 머신 및 워크로드 아이덴티티의 tbot 또는 Teleport Terraform 공급자가 공유 시크릿 없이 Teleport에 인증할 수 있도록 하는 데 사용됩니다.

kind: token
version: v2
metadata:
  name: example-bot
spec:
  roles: [Bot]
  join_method: bitbucket
  bot_name: example
  bitbucket:
    # The URL of the workspace-specific OIDC identity provider. This can be
    # found in the repository settings under "Pipelines" and "OpenID Connect".
    identity_provider_url: $IDENTITY_PROVIDER_URL

    # The audience of the OIDC tokens issued by Bitbucket. This can be found in
    # the repository settings under "Pipelines" and "OpenID Connect".
    audience: $AUDIENCE

    # allow specifies the rules by which the Auth Service determines if `tbot`
    # should be allowed to join. All parameters in a given allow entry must
    # match for the join attempt to succeed, but many allow rules may be
    # provided. One or both of `workspace_uuid` and `repository_uuid` are
    # required; all other fields are optional.
    allow:
      - # The UUID of a workspace whose runs should be allowed to connect. This
        # value can be found in the repository settings under "Pipelines" and
        # "OpenID Connect". It must be enclosed in braces, i.e. `{...}`. At
        # least `workspace_uuid` or `repository_uuid` must be provided.
        workspace_uuid: '{WORKSPACE_UUID}'

        # The UUID of a repository whose runs should be allowed to connect. This
        # value can be found in the repository settings under "Pipelines" and
        # "OpenID Connect". It must be enclosed in braces, i.e. `{...}`. At
        # least `workspace_uuid` or `repository_uuid` must be provided.
        repository_uuid: '{REPOSITORY_UUID}'

        # If set, only steps tagged with the deployment environment linked to
        # this UUID will be allowed to connect. This value can be found in the
        # repository settings under "Pipelines" and "OpenID Connect" when a
        # deployment environment is selected from the drop-down menu. It must be
        # enclosed in braces, i.e. `{...}`. Optional.
        deployment_environment_uuid: '{DEPLOYMENT_ENVIRONMENT_UUID}'

        # If set, only workflows running on the named branch will be allowed to
        # connect. Optional.
        branch_name: "main"

Oracle Cloud: oracle#

Oracle 합류 방법은 Oracle Cloud Compute 인스턴스에서 실행되는 모든 Teleport 프로세스에서 사용할 수 있습니다.

# token.yaml
kind: token
version: v2
metadata:
  # The token name is not a secret because instances must prove that they are
  # running in your Oracle tenant to use this token.
  name: oracle-token
spec:
  # Use the minimal set of roles required (e.g. Node, Proxy, App, Kube, DB, WindowsDesktop).
  roles: [Node]

  # Set the join method allowed for this token.
  join_method: oracle

  oracle:
    allow:
      # OCID of the tenancy to allow instances to join from. Required.
      - tenancy: "ocid1.tenancy.oc1..<unique_ID>"
        # (Optional) OCIDs of compartments to allow instances to join from. Only the direct parent
        # compartment applies; i.e. nested compartments are not taken into account.
        # If empty, instances can join from any compartment in the tenancy.
        parent_compartments: ["ocid1.compartment.oc1..<unique_ID>"]
        # (Optional) Regions to allow instances to join from. Both full names ("us-phoenix-1")
        # and abbreviations ("phx") are allowed. If empty, instances can join from any region.
        regions: ["example-region"]
        # (Optional) OCIDs of specific compute instances that should be allowed to join.
        # If empty, any instance matching the other fields is allowed.
        # The instances field is supported in Teleport v18.4.0+.
        instances: ["ocid1.instance.oc1.<region>.<unique_ID>"]