조건부 접근 문

조건부 접근 문 (Conditional access statements)

조건부 접근 문(conditional access statement)과 그 형식화 방법을 설명해 드릴게요. 조건부 접근 문은 워크로드 아이덴티티 페더레이션 도중 HCP로 보내지는 외부 자격 증명의 자격 여부를 판단하는 불리언 표현식이에요. HCP가 조건부 접근 문을 true로 평가하면 해당 자격 증명을 수락해요.

조건부 접근 문은 어떤 자격 증명과 워크로드가 HCP 액세스 토큰을 받을 수 있는지에 대한 추가적인 제어를 가능하게 해요. 의도된 워크로드만 HCP 서비스에 접근할 수 있게 보장하는 데 도움을 줘요.

출처: 문서

본문

표현식 만들기

단일 표현식은 선택자(selector)와 값(value)이 함께 있는 매칭 연산자예요. 일반 텍스트 형식으로 작성되며 불리언 로직과 괄호를 지원해요. 일반적으로 리터럴 문자열 안을 제외하고 공백은 무시돼요.

매칭 연산자

모든 매칭 연산자는 선택자나 값을 사용해 어떤 데이터를 매칭할지 정해요. 다음 레퍼런스는 선택자와 값을 매칭하기 위한 지원 표현식을 제공해요.

// Equality & Inequality checks
<Selector> == "<Value>"
<Selector> != "<Value>"

// Emptiness checks
<Selector> is empty
<Selector> is not empty

// Contains checks or Substring Matching
"<Value>" in <Selector>
"<Value>" not in <Selector>
<Selector> contains "<Value>"
<Selector> not contains "<Value>"

// Regular Expression Matching
<Selector> matches "<Value>"
<Selector> not matches "<Value>"

선택자 (Selectors)

선택자는 표현식을 만들어요. 점 표기법(name.name.name)으로 선택자를 정의해요. 각 이름은 ASCII 문자로 시작해야 하고, ASCII 문자·숫자·밑줄을 포함할 수 있어요.

선택자의 일부가 맵 값을 참조할 때는 .<map key name> 대신 ["<map key name>"] 형식을 사용할 수 있어요. 이 구문은 그 자체로 유효한 선택자가 아닌 맵 키를 사용할 수 있게 해줘요.

다음 예시는 선택자를 형식화하는 방법을 보여줘요.

// Accessing nested claims
// https://cloud.google.com/compute/docs/instances/verifying-instance-identity#payload
jwt_claims.google.compute_engine.project_id

// Also selects the same key
jwt_claims["google"]["compute_engine"]["project_id"]

AWS

AWS에서는 AWS GetCallerIdentity 응답에 해당하는 다음 선택자를 사용할 수 있어요.

  • aws.arn: 호출 엔티티와 연결된 AWS ARN
  • aws.account_id: 호출 엔티티를 소유하거나 포함하는 계정의 AWS 계정 ID 번호
  • aws.user_id: 호출 엔티티의 고유 식별자

OIDC 제공자

OIDC 토큰을 HCP 접근 권한으로 교환할 때, 조건부 접근 문은 토큰의 모든 클레임을 jwt_claims. 접두어로 접근할 수 있어요. 다음 예시는 GitHub Actions Workflow용 토큰이에요.

{
  "jti": "example-id",
  "sub": "repo:octo-org/octo-repo:environment:prod",
  "environment": "prod",
  "aud": "https://github.com/octo-org",
  "ref": "refs/heads/main",
  "sha": "example-sha",
  "repository": "octo-org/octo-repo",
  "repository_owner": "octo-org",
  "actor_id": "12",
  "repository_visibility": "private",
  "repository_id": "74",
  "repository_owner_id": "65",
  "run_id": "example-run-id",
  "run_number": "10",
  "run_attempt": "2",
  "runner_environment": "github-hosted",
  "actor": "octocat",
  "workflow": "example-workflow",
  "head_ref": "",
  "base_ref": "",
  "event_name": "workflow_dispatch",
  "ref_type": "branch",
  "job_workflow_ref": "octo-org/octo-automation/.github/workflows/oidc.yml@refs/heads/main",
  "iss": "https://token.actions.githubusercontent.com",
  "nbf": 1632492967,
  "exp": 1632493867,
  "iat": 1632493567
}

다음 표는 유효한 선택자의 전체가 아닌 목록과 그들이 매칭하는 값을 담고 있어요.

| 선택자 | 매칭 값 | | jwt_claims.repository | octo-org/octo-repo | | jwt_claims.workflow | example-workflow | | jwt_claims.environment | prod |

값 (Values)

연산자는 표현식을 평가할 때 값을 매칭해요. 값은 유효한 선택자, 숫자, 또는 문자열이 될 수 있어요. 숫자는 10진 정수 또는 부동 소수점 숫자일 수 있어요.

값에 따옴표를 사용하는 것이 모범 사례예요. 문자열을 인용할 때는 큰따옴표 또는 백틱을 사용할 수 있어요. 백틱으로 감싸면 값은 raw 문자열로 처리되어 \n 같은 이스케이프 시퀀스가 확장돼요.

복합 표현식 (Compound expressions)

표현식을 더 큰 복합 표현식으로 연결하는 여러 방법이 있어요. 다음 중 하나 이상으로 표현식을 연결할 수 있어요.

  • 논리 or
  • 논리 and
  • 논리 not
  • 괄호로 묶기 (grouping)
  • 매칭 표현식

다음 예시는 복합 표현식의 일반적인 구문 옵션을 보여줘요.

// Logical Or - evaluates to true if either sub-expression does
<Expression 1> or <Expression 2>

// Logical And - evaluates to true if both sub-expressions do
<Expression 1 > and <Expression 2>

// Logical Not - evaluates to true if the sub-expression does not
not <Expression 1>

// Grouping - Overrides normal precedence rules
( <Expression 1> )

// Inspects data to check for a match
<Matching Expression 1>

표현식에는 표준 연산자 우선순위가 적용돼요. 예를 들어 다음 두 표현식은 동등해요.

<Expression 1> and not <Expression 2> or <Expression 3>

( <Expression 1> and (not <Expression 2> )) or <Expression 3>

예시 (Examples)

다음 예시는 조건부 접근 문 표현식의 일반적인 패턴을 보여줘요.

matches를 사용해 AWS Role my-app-role을 가진 워크로드의 접근을 제한해요.

`aws.arn matches ^arn:aws:sts::123456789012:assumed-role/my-app-role/`

matches와 or을 사용해 AWS Role my-app-role 또는 my-other-app-role을 가진 워크로드의 접근을 제한해요.

`aws.arn matches ^arn:aws:sts::123456789012:assumed-role/my-app-role/ or aws.arn matches ^arn:aws:sts::123456789012:assumed-role/my-other-app-role/`

==를 사용해 Service Account 106356042740441904560를 가진 GCP 워크로드에 대해서만, 그리고 프로젝트 ID my-app-project-191923에서 실행되는 워크로드에 대해서만 접근을 제한해요.

`jwt_claims.sub == 106356042740441904560 and jwt_claims.google.compute_engine.project_id == my-app-project-191923`

더 알아보기 (Learn more)