Vault로 SSO 구성하기
Vault로 SSO 구성하기 (Configure SSO with Vault)
제로 트러스트(Zero-trust) 아키텍처를 구현하려면 조직 내 서비스에 아이덴티티 기반 접근을 제공해야 해요. OpenID Connect (OIDC)는 클라이언트가 아이덴티티 공급자를 통해 자신의 정체성을 확인할 수 있게 해줘요. Vault 1.9.0은 authorization code 흐름으로 Vault를 OIDC 아이덴티티 공급자로 구성하는 기능을 도입했고, Nomad 1.5.0은 단일 로그온(SSO) 방식으로서 OIDC 지원을 도입했어요. Nomad 1.5.0부터 OIDC를 사용해 사용자를 인증하고 그 권한을 Nomad ACL 역할과 정책에 매핑할 수 있어요.
출처: 문서
본문
이 가이드에서는 Vault를 OIDC 공급자로, Nomad를 그 클라이언트로 설정할 거예요.
참고: 이 가이드에서 Nomad는 기밀(confidential) OIDC 클라이언트로 작동해요. 공용(public) OIDC 클라이언트를 구성하려면 OIDC 공급자 문서를 참조해요.
사전 요구 사항 (Prerequisites)
이 가이드에서 설명하는 작업을 수행하려면 다음이 필요해요:
- Nomad 환경. Nomad를 설치하고 클러스터를 만들려면 get started 튜토리얼을 참조해요.
- 버전 1.10 이상의 Vault 환경. Vault를 로컬에 설치하려면 Vault 설치 가이드를, HCP에 Vault 클러스터를 만들려면 참조해요.
참고: 이 기능은 Vault 1.9에서 Technical Preview 기능으로 처음 도입됐어요. Vault 1.10부터 일반 공개(GA)되었어요.
정책 요구 사항 (Policy requirements)
이 가이드의 목적을 위해 개발 모드로 실행되는 Vault를 작업할 때 root 토큰을 사용할 거예요.
비개발 Vault 환경에서 작업할 때는 토큰 정책에 다음 권한이 포함되어야 해요:
path "identity/*" {
capabilities = [ "create", "read", "update", "delete", "list" ]
}
# To enable userpass auth method
path "sys/auth/userpass" {
capabilities = [ "create", "read", "update", "delete" ]
}
# To create a new user, "end-user" for userpass
path "auth/userpass/users/*" {
capabilities = [ "create", "read", "update", "delete", "list" ]
}
자세한 내용은 Vault 정책 튜토리얼을 참조해요.
Vault 시작 (Start Vault)
터미널에서 root를 루트 토큰으로 하는 Vault 개발 서버를 시작해요.
Vault 개발 서버는 기본적으로 127.0.0.1:8200에서 실행돼요. 서버는 이제 초기화되고 봉인이 해제(unsealed)되었어요.
경고
프로덕션에서 Vault 개발 서버를 실행하지 마세요. 이 방식은 인메모리 데이터베이스로 Vault 서버를 시작하며 테스트 목적으로만 사용해야 해요.
다른 터미널 세션을 열고 Vault 서버 주소에 대한 환경 변수를 내보내요.
Vault 토큰에 대한 환경 변수를 내보내요.
참고: 이러한 작업을 위해 Vault의 root 토큰을 사용할 수 있어요. 그러나 루트 토큰은 초기 설정이나 비상 상황에서만 사용할 것을 권장해요. 모범 사례로 정책 요구 사항을 충족하는 인증 방법이나 토큰을 사용해요.
Vault 서버가 준비됐어요.
- HCP Portal을 실행하고 로그인해요.
- 왼쪽 탐색 창에서 Vault를 클릭해요.
- Vault clusters 창에서 vault-cluster를 클릭해요.
- Cluster URLs 아래에서 Public Cluster URL을 클릭해요. 이렇게 하면 URL이 클립보드에 복사돼요.
- 터미널에서
VAULT_ADDR환경 변수를 HCP에서 복사한 공용 클러스터 URL로 설정해요.
- Overview 페이지로 돌아가 Generate token을 클릭해요. 토큰을 생성하는 데 몇 시간이 걸릴 수 있어요.
- Copy를 클릭해 Admin Token을 복사해요.
- 터미널로 돌아가
VAULT_TOKEN환경 변수를 HCP에서 복사한 토큰으로 설정해요.
VAULT_NAMESPACE환경 변수를admin으로 설정해요.
admin 네임스페이스는 HCP Vault가 자동으로 만드는 최상위 네임스페이스예요. 기본적으로 모든 CLI 작업은 이 환경 변수에 정의된 네임스페이스를 사용해요.
- Vault 클러스터에 대한 연결을 확인해요.
Key Value
--- -----
Recovery Seal Type shamir
Initialized true
Sealed false
Total Recovery Shares 1
Threshold 1
Version 1.9.2+ent
Storage Type raft
...snipped...
Vault Dedicated 서버가 준비됐어요.
Vault 인증 구성 (Configure Vault authentication)
Vault auth methods는 클라이언트를 인증하고 아이덴티티와 정책을 할당해요. Vault가 OIDC 공급자로 작동할 때 아이덴티티의 원천이며 이러한 auth methods가 그 아이덴티티를 검증해요.
- 기본 경로에서 userpass auth method를 활성화해요.
- 비밀번호가
password인end-user라는 사용자를 만들어요.
password="password" \
token_ttl="1h"
이 사용자는 Vault로 인증되며 기본 접근 정책이 할당돼요.
더 알아보기: 자세한 내용은 Userpass Auth Method 문서를 참조해요.
Vault 아이덴티티 엔티티와 그룹 만들기 (Create Vault identity entity and group)
클라이언트는 Vault 서버에서 활성화된 다양한 아이덴티티 공급자와 여러 계정을 가질 수 있어요. Vault 클라이언트는 엔티티(entity)로 매핑될 수 있고, 인증 공급자의 해당 계정은 별칭(alias)으로 매핑될 수 있어요.
end-user에 대한 세부 정보로 아이덴티티 엔티티를 만들어요.
name="end-user" \
disabled=false
- 엔티티에 할당된 ID를 저장하는
ENTITY_ID라는 환경 변수를 만들어요.
engineering이라는 아이덴티티 그룹을 만들고end-user를 멤버로 추가해요.
name="engineering" \
member_entity_ids="$ENTITY_ID"
- 그룹에 할당된 ID를 저장하는
GROUP_ID라는 환경 변수를 만들어요.
end-user 엔티티는 engineering 그룹의 멤버예요. 엔티티 별칭은 엔티티를 인증 방법의 클라이언트에 매핑해요. 이 매핑에는 엔티티 ID와 인증 accessor ID가 필요해요.
- userpass 인증 방법의 accessor 값을 저장하는
USERPASS_ACCESSOR라는 변수를 만들어요.
end-user엔티티를end-user사용자와 매핑하는 엔티티 별칭을 만들어요.
name="end-user" \
canonical_id="$ENTITY_ID" \
mount_accessor="$USERPASS_ACCESSOR"
엔티티와 사용자는 서로 별칭이에요.
더 알아보기: 엔티티와 그룹 튜토리얼에서 아이덴티티에 대해 더 알아보세요.
Vault OIDC 클라이언트 만들기 (Create a Vault OIDC client)
Vault OIDC 클라이언트는 OIDC 할당(assignment)이라는 리소스, 암호화 키, 클라이언트 콜백 URL, 검증 시 TTL(time-to-live)을 함께 연결해요.
OIDC 할당은 이 클라이언트로 인증할 수 있는 Vault 엔티티와 그룹의 목록을 설명해요.
end-user엔티티와engineering그룹을 승인하는my-assignment라는 할당을 만들어요.
entity_ids="${ENTITY_ID}" \
group_ids="${GROUP_ID}"
Vault OIDC 인증 과정은 인증 흐름에서 생성되는 JSON 웹 토큰(JWT)을 서명하고 검증할 암호화 키가 필요해요.
my-key라는 키를 만들어요.
allowed_client_ids="*" \
verification_ttl="2h" \
rotation_period="1h" \
algorithm="RS256"
allowed_client_ids가 *로 설정되어 있으므로 이 키는 모든 Vault OIDC 클라이언트가 사용할 수 있어요.
nomad라는 OIDC 클라이언트를 만들어요.
redirect_uris="http://localhost:4649/oidc/callback,http://localhost:4200/ui/settings/tokens" \
assignments="my-assignment" \
key="my-key" \
id_token_ttl="30m" \
access_token_ttl="1h"
redirect_uris 플래그는 클라이언트의 콜백 URL을 설명하며, 값은 기본 포트에서 실행되는 Nomad 서비스의 주소예요.
assignments 플래그는 my-assignment에 정의된 엔티티와 그룹에만 접근을 제한해요.
id_token_ttl 플래그는 ID 토큰의 만료를 30분으로 설정해요.
access_token_ttl 플래그는 액세스 토큰의 만료를 1시간으로 설정해요.
nomad클라이언트의client_id필드를 저장하는CLIENT_ID라는 환경 변수를 만들어요.
Vault OIDC 공급자 만들기 (Create a Vault OIDC provider)
Vault OIDC 공급자는 하나 이상의 클라이언트와 Vault OIDC 스코프를 지원해요. 이러한 스코프는 템플릿으로 표현되는 메타데이터 클레임을 정의해요. 클레임은 사용자와 OIDC 서비스에 대한 정보를 포함하는 키-값 쌍이에요.
- 사용자 스코프 템플릿을 저장하는
USER_SCOPE_TEMPLATE라는 환경 변수를 만들어요.
- 사용자 스코프 템플릿으로
user라는 Vault OIDC 스코프를 정의해요.
description="The user scope provides claims using Vault identity entity metadata" \
template="$(echo ${USER_SCOPE_TEMPLATE} | base64)"
- 그룹 스코프 템플릿을 저장하는
GROUPS_SCOPE_TEMPLATE라는 환경 변수를 만들어요.
이 템플릿은 정의된 모든 그룹의 이름을 검색해요.
- 그룹 스코프 템플릿으로
groups라는 Vault OIDC 스코프를 정의해요.
description="The groups scope provides the groups claim using Vault group membership" \
template="$(echo ${GROUPS_SCOPE_TEMPLATE} | base64)"
my-provider라는 Vault OIDC 공급자를 만들고 클라이언트 ID와 스코프 목록을 제공해요. 공급자는nomad클라이언트에 접근을 부여해요.
allowed_client_ids="${CLIENT_ID}" \
scopes_supported="groups"
Vault Dedicated는 issuer URL에 프라이빗 주소를 사용해요. 이 가이드에서는 공용 URL과 일치하도록 issuer 값을 재정의할 거예요.
issuer="$(echo $VAULT_ADDR)" \
allowed_client_ids="${CLIENT_ID}" \
scopes_supported="groups"
- Vault OIDC 구성 엔드포인트를 표시해요.
--header "X-Vault-Namespace: $VAULT_NAMESPACE" \
$VAULT_ADDR/v1/identity/oidc/provider/my-provider/.well-known/openid-configuration | jq
- Vault OIDC 공개 키를 표시해요.
--header "X-Vault-Namespace: $VAULT_NAMESPACE" \
$VAULT_ADDR/v1/identity/oidc/provider/my-provider/.well-known/keys | jq
Nomad 시작 (Start Nomad)
Nomad 개발 에이전트는 서버와 클라이언트가 포함된 Nomad 인스턴스를 생성해요. 자세한 내용은 클러스터 시작 튜토리얼을 참조해요.
다른 터미널에서 ACL이 활성화된 개발 모드로 Nomad 에이전트를 시작해요.
==> No configuration files loaded
==> Starting Nomad agent...
==> Nomad agent configuration:
Advertise Addrs: HTTP: 127.0.0.1:4646; RPC: 127.0.0.1:4647; Serf: 127.0.0.1:4648
Bind Addrs: HTTP: [127.0.0.1:4646]; RPC: 127.0.0.1:4647; Serf: 127.0.0.1:4648
Client: true
Log Level: DEBUG
Region: global (DC: dc1)
Server: true
Version: 1.5.0
...snip...
Nomad 서버가 준비됐어요.
Nomad OIDC 인증 구성 (Configure Nomad OIDC auth)
my-provider라는 Vault OIDC 공급자의issuer필드를 저장하는ISSUER라는 환경 변수를 만들어요.
--header "X-Vault-Namespace: $VAULT_NAMESPACE" \
$VAULT_ADDR/v1/identity/oidc/provider/my-provider/.well-known/openid-configuration | jq -r .issuer)
nomad라는 Vault OIDC 클라이언트의client_secret필드를 저장하는CLIENT_SECRET이라는 환경 변수를 만들어요.
- 부트스트랩 과정을 실행하고, 관리 토큰의 값을 저장해
NOMAD_TOKEN환경 변수로 내보내요.
$ export NOMAD_TOKEN
- "default" 네임스페이스에 읽기 접근을 허용하는 Nomad 정책을 만들어요.
acl_policy_engineering_read.hcl라는 파일을 만들고 다음 내용을 추가한 후 저장해요.
policy = "read"
}
node {
policy = "read"
}
정책을 적용해요.
- 엔지니어에게 할당할 정책을 포함하는 해당 역할을 만들어요.
-name=engineering-read \
-policy=engineering-read
- OIDC auth method의 구성을 만들어요.
acl_auth_method.json이라는 파일을 만들고 다음 내용을 추가한 후 $ISSUER, $CLIENT_ID, $CLIENT_SECRET를 각각의 환경 변수에 저장된 값으로 대체하고 저장해요.
"OIDCDiscoveryURL": $ISSUER,
"OIDCClientID": $CLIENT_ID,
"OIDCClientSecret": $CLIENT_SECRET,
"BoundAudiences": [$CLIENT_ID],
"OIDCScopes": ["groups"],
"AllowedRedirectURIs": [
"http://localhost:4649/oidc/callback",
"http://localhost:4646/ui/settings/tokens"
],
"ListClaimMappings": {
"groups": "roles"
}
}
ListClaimMappings 필드는 OIDC 공급자의 어떤 클레임을 Nomad의 어떤 ACL 개념에 매핑할지 지정해요. 앞서 만든 Vault "group"은 Nomad의 "role"에 매핑돼요.
- 새 OIDC 인증 방법을 만들고 Vault OIDC 공급자를 사용하도록 구성해요.
-default=true \
-name=vault \
-token-locality=global \
-max-token-ttl="10m" \
-type=oidc \
-config @acl_auth_method.json
- OIDC 클레임을 Nomad 정책과 역할로 평가하는 바인딩 규칙을 만들어요.
-auth-method=vault \
-bind-type=role \
-bind-name="engineering-read" \
-selector="engineering in list.roles"
Nomad OIDC 인증이 구성됐고 end-user가 인증할 준비가 됐어요.
Nomad로 인증 (Authenticate with Nomad)
Nomad에 인증해요. vault가 기본 방법으로 구성됐으므로 -method 플래그는 선택 사항이에요.
브라우저에서 Vault 로그인 화면이 열려요. Method 드롭다운에서 Username을 선택하고 자격 증명으로 end-user와 password를 입력해요.
nomad login 명령은 인증이 성공했음을 확인하고 생성된 Nomad ACL 토큰을 표시해요.
Accessor ID = 48008488-21ae-35d7-f1d6-0066a7eb902a
Secret ID = d7a803e6-abd6-a80e-dd95-5f88d904cc9e
Name = vault
Type = client
Global = true
Create Time = 2023-01-13 10:06:35.933899 +0000 UTC
Expiry Time = 2023-01-13 10:16:35.933899 +0000 UTC
Create Index = 19
Modify Index = 19
Policies = []
Roles
ID Name
197deab1-a963-91fc-2936-05923eecf0c0 engineering-read
다음 단계 (Next steps)
이 가이드에서는 Vault를 OIDC 공급자로, Nomad를 클라이언트로 구성했어요. Vault를 OIDC 공급자로 구성하는 방법에 대해 더 알아보세요.