ACL 정책 템플릿에 대한 중복 제거 영향 해결하기

ACL 정책 템플릿에 대한 중복 제거 영향 해결하기

identity 중복 제거 중 이름이 변경된 엔티티·그룹에 대한 템플릿화된 ACL 정책 동작을 수정해요.

전제 조건(Assumptions)

  • Vault 1.19 이상을 실행 중이에요.
  • 시스템 로그에 중복 제거 이름 변경 대상이 있어요.
  • 관련 Vault 서버 또는 클러스터에 대한 관리자 권한이 있어요.

출처: 문서

본문

이름 변경이 ACL 정책에 미치는 영향(How renaming affects ACL policies)

운영자는 인증된 엔티티의 특정 속성에 따라 동적으로 해석되는 권한을 지정하기 위해 정책 템플릿을 사용해요. 중복 제거 중 Vault는 중복 identity를 가진 엔티티나 그룹에 UUID(범용 고유 식별자)를 하나를 제외한 모든 엔티티에 덧붙여 이름을 바꿔 향후 중복을 방지해요.

템플릿화된 ACL 정책이 엔티티나 그룹 이름에 의존한다면, 중복 identity의 이름 변경이 정책의 의미를 의도치 않게 바꿀 수 있어요. 실제로 identity 중복 제거가 기존 리소스에 의도하지 않은 접근을 부여할 가능성은 낮아요. 이름이 변경된 identity에는 다른 리소스 경로와 충돌하지 않아야 하는 UUID가 포함되기 때문이에요. 하지만 연결된 리소스 정책이 이전 엔티티나 그룹 이름을 참조한다면 중복 제거 후 이름 변경이 기존 리소스에 대한 접근을 제거할 수 있어요.

예를 들어 다음 템플릿화된 ACL 정책이 사용자에게 kv 플러그인 접근 권한을 부여한다고 가정해요.

path "kv/users/{{identity.entity.name}}/*" {
    capabilities = ["read", "create", "update"]
}

이 정책은 janine이라는 사용자 엔티티에게 kv/users/janine/ 경로의 키-값 쌍을 읽고 쓸 권한을 부여해요. janine이라는 중복 엔티티가 있다면 Vault는 중복 제거 중 하나를 제외한 모든 엔티티를 janine-<UUID>로 이름을 바꿔요.

이제 ACL 정책은 이름이 변경된 엔티티에게 더 이상 kv/users/janine/ 경로에 대한 접근을 부여하지 않아요. 이름이 변경된 엔티티는 여전히 kv 플러그인에 접근할 수 있지만, 사용자는 더 이상 kv/users/janine/ 아래에 저장된 데이터에 접근할 수 없어요.

영향을 받는 ACL 정책 찾기(Find affected ACL policies)

중복 제거는 엔티티나 그룹 이름 키에 의존하는 템플릿화된 ACL 정책을 깨뜨릴 수 있어요.

템플릿 키 설명
identity.entity.name 엔티티 이름
identity.entity.aliases..name 주어진 마운트의 엔티티 별칭 이름
identity.groups.ids..name 주어진 그룹 ID의 그룹 이름
identity.groups.names..id 주어진 그룹 이름의 그룹 ID
identity.groups.names..metadata. 주어진 그룹 이름과 키의 메타데이터

다음 bash 스크립트로 엔티티나 그룹 이름을 사용하는 템플릿화된 정책을 확인할 수 있어요.

policy_list=$(vault policy list)
for policy in ${policy_list}; do

  # 정책 세부 정보를 가져옵니다
  policy_details=$(vault policy read ${policy})
  # name 기반 템플릿 키가 있는지 확인합니다
  if echo "${policy_details}" | grep -q "\.name"; then
    echo ""
    echo "Policy name: ${policy}"
  fi
  echo "${policy_details}" |
    tr -s ' ' '\n' |
    grep "\.name" --label="  template key" -H
done
policy_list=$(
  curl --silent \
    --request GET \
    --header "X-Vault-Token: ${VAULT_TOKEN}" \
    ${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/sys/policy \
  | jq .data.policies | jq -c '.[]' | tr -d '"'
)
for policy in ${policy_list}; do

  # 정책 세부 정보를 가져옵니다
  policy_details=$(
    curl --silent \
      --request GET \
      --header "X-Vault-Token: ${VAULT_TOKEN}" \
      ${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/sys/policy/${policy} \
    | jq '.data.rules' | sed 's/\\"/"/g' | sed 's/\\n/ /g'
  )
  # name 기반 템플릿 키가 있는지 확인합니다
  if echo "${policy_details}" | grep -q "\.name"; then
    echo ""
    echo "Policy name: ${policy}"
  fi
  echo "${policy_details}" |
    tr -s ' ' '\n' |
    grep "\.name" --label="  template key" -H
done

반환된 정책·템플릿 키 목록을 시스템 로그에서 확인한 중복 제거 대상 목록과 비교해 정책이 중복 제거 후 깨질지 여부를 판단해요.

중복 제거 중 깨질 수 있는 정책을 확인했다면, 관련 팀과 상의해 정책이 여전히 사용되는지, 이름 변경 문제를 중복 제거 전에 처리할지 후에 처리할지 결정해요.

수정이 필요한 정책을 찾았다면 사용자 접근을 고치는 방법은 두 가지예요.

  1. 관련 템플릿화된 ACL 정책을 업데이트한다.
  2. 영향을 받는 리소스를 이동한다.

해결책 1: 관련 ACL 정책 업데이트(Update relevant ACL policies)

중복 제거로 깨진 ACL 정책 템플릿을 다루는 가장 쉬운 방법은 영향을 받는 엔티티에게 이전 리소스에 대한 접근을 명시적으로 부여하는 새 정책을 정의하거나 기존 정책에 규칙을 추가하는 거예요.

중복 identity가 많다면 이름이 변경된 엔티티에 사용자 지정 메타데이터 필드(예: prev_name)를 미리 채우는 게 더 쉬울 수 있어요. 그런 다음 엔티티 이름 대신 그 사용자 지정 메타데이터 필드를 사용하는 단일 정책을 만들고, 그 정책을 이름이 변경된 엔티티에 연결해요.

중복 제거 후 더 이상 동작하지 않을 템플릿화된 ACL 정책에 현재 연결된 엔티티 이름 목록이 담긴 rename-targets.txt 파일이 있다고 가정해요.

  1. {namespace}/identity/entity/name/{name} 엔드포인트와 vault write를 사용해 대상 항목에 현재 엔티티 이름으로 설정된 old_name이라는 사용자 지정 메타데이터 필드를 업데이트해요.

    while read entity_name; do
      if [[ "" = "${entity_name}" ]]; then continue; fi
      # 새 메타데이터 필드로 페이로드 파일을 만듭니다
      echo -n '{"metadata": { "old_name": "' ${entity_name} '"}}' > ./metadata.json
      # 메타데이터를 엔티티에 저장합니다
      vault write /identity/entity/name/${entity_name} @metadata.json
    done < rename-targets.txt
    
  2. 엔티티 이름 참조를 메타데이터 필드 참조로 바꾸는 새 템플릿화된 ACL 정책 파일을 만들어요. 예:

    path "kv/users/{{identity.entity.metadata.old_name}}/*" {
      capabilities = ["read", "create", "update"]
    }
    
  3. vault policy write로 정책 정의 파일을 사용해 새 ACL 정책을 만들어요.

    $ vault policy write <policy_name> <path_to_policy_file>
    

    예:

    $ vault policy write "kv-access-preservation" ./dedupe-policy.hcl
    
  4. {namespace}/identity/entity/name/{name} 경로를 vault read로 읽어 기존 정책 할당을 읽고 대상 엔티티에 새 정책을 추가해요. 예:

    policy_name = "<policy_name>"
    while read entity_name; do
      if [[ "" = "${entity_name}" ]]; then continue; fi
      # 기존 정책 할당에 새 정책을 추가한 페이로드 파일을 만듭니다
      vault read -field policies -format json /identity/entity/name/${entity_name} \
        | jq ". + [\"${policy_name}\"] | {policies: .}" > policy_update.json
      # 엔티티의 정책 할당을 업데이트합니다
      vault write /identity/entity/name/${entity_name} @policy_update.json
    done < rename-targets.txt
    

(curl/API 버전) 중복 제거 후 더 이상 동작하지 않을 템플릿화된 ACL 정책에 현재 연결된 엔티티 이름 목록이 담긴 rename-targets.txt 파일이 있다고 가정해요.

  1. {namespace}/identity/entity/name/{name} 엔드포인트를 사용해 대상 항목에 현재 엔티티 이름으로 설정된 old_name이라는 사용자 지정 메타데이터 필드를 업데이트해요.

    while read entity_name; do
      if [[ "" = "${entity_name}" ]]; then continue; fi
      # 새 메타데이터가 담긴 페이로드 파일을 만듭니다
      echo -n '{"metadata": { "old_name": "' ${entity_name} '"}}' > ./metadata.json
      # 메타데이터를 엔티티에 저장합니다
      curl --request POST \
        --header "X-Vault-Token: ${VAULT_TOKEN}" \
        --data @./metadata.json \
        ${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/identity/entity/name/${entity_name}
    done < rename-targets.txt
    
  2. 엔티티 이름 참조를 메타데이터 필드 참조로 바꾸는 새 템플릿화된 ACL 정책 파일을 만들어요. 예:

    path "kv/users/{{identity.entity.metadata.old_name}}/*" {
      capabilities = ["read", "create", "update"]
    }
    
  3. 정책 파일을 이스케이프하고 정책 세부 정보로 {namespace}/sys/policy/{policy_name}에 POST 호출을 해요.

    $ jq -Rs '{ "policy": . | gsub("[\\r\\n\\t]"; "") }' < path_to_policy_file > | curl \
        --request POST                            \
        --header "X-Vault-Token: ${VAULT_TOKEN}"  \
        "$(</dev/stdin)"                          \
        ${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/sys/policy/<policy_name>
    

    예:

    $ jq -Rs '{ "policy": . | gsub("[\\r\\n\\t]"; "") }' ./dedupe-policy.hcl | curl \
        --request POST                            \
        --header "X-Vault-Token: ${VAULT_TOKEN}"  \
        --data "$(</dev/stdin)"                   \
        ${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/sys/policy/kv-access-preservation
    
  4. {namespace}/identity/entity/name/{name} 엔드포인트에 GET 호출을 해 기존 정책 할당을 읽고 대상 엔티티에 새 정책을 추가해요. 예:

    policy_name = "<policy_name>"
    while read entity_name; do
      if [[ "" = "${entity_name}" ]]; then continue; fi
      # 기존 정책 할당에 새 정책을 추가한 페이로드 파일을 만듭니다
      curl --request GET \
        --header "X-Vault-Token: ${VAULT_TOKEN}" \
        ${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/identity/entity/name/${entity_name} \
        | jq ".data.policies + [\"${policy_name}\"] | {policies: .}" > policy_update.json
      # 엔티티의 정책 할당을 업데이트합니다
      curl --request POST \
        --header "X-Vault-Token: ${VAULT_TOKEN}" \
        --data @policy_update.json \
        ${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/identity/entity/name/${entity_name}
    done < rename-targets.txt
    

해결책 2: 영향을 받는 리소스 이동(Move the affected resource)

어떤 리소스는 이동할 수 없고, 어떤 리소스는 이동하기 어려워요. 이름 변경으로 영향을 받는 리소스를 옮기기로 결정했다면:

  1. 관련 리소스와 연결된 마운트 경로를 목록으로 정리해요.
  2. 중복 제거 플래그를 활성화하기 전에 어떤 리소스를 마이그레이션할지 결정해요.
    • 중복 제거 전에 마이그레이션하는 리소스는 중복 제거가 완료될 때까지 이전·새 경로 모두에서 사용할 수 없어요.
    • 중복 제거 후 마이그레이션하는 리소스는 마이그레이션이 완료될 때까지 사용할 수 없어요.
  3. 중복 제거 전에 마이그레이션으로 표시된 리소스를 이동하고, 관련 사용자에게 중복 제거가 완료될 때까지 경로를 사용할 수 없다고 알려요.
  4. Vault의 중복 제거 옵션을 활성화해요.
  5. 중복 제거 후 마이그레이션으로 표시된 리소스를 이동하고, 관련 사용자에게 마이그레이션이 완료되고 변경이 완전히 전파될 때까지 경로를 사용할 수 없다고 알려요.

더 알아보기 (Learn more)

  • identity 중복 제거 개요와 단계별 절차를 살펴보세요.
  • different-case 엔티티 별칭 중복 수정, 엔티티·그룹 중복 수정을 확인해 보세요.