거래 정책 평가

다자간 계산에서 트랜잭션에 서명하기 전에 인스턴스의 트랜잭션 정책에 따라 트랜잭션을 평가합니다. 이 문서에서는 평가되는 정책, 정책이 수명 주기를 거치는 방식, 정책이 확인할 수 있는 항목, 트랜잭션이 거부되는 이유를 설명합니다.

거래 평가 방법

트랜잭션 정책은 단일 Cedar permit 또는 forbid 문입니다. 서명자가 CreateTransaction를 호출하면 인스턴스는 Transaction.schema의 파서를 사용하여 Transaction.payload의 서명되지 않은 트랜잭션을 디코딩하고 키 공유가 사용되기 전에 트랜잭션에 대해 시행된 모든 정책을 평가합니다. 정책은 상태가 ACTIVE 또는 PENDING_DISABLED일 때 적용됩니다. 자세한 내용은 정책 수명 주기를 참조하세요.

이 결정은 다음 세 가지 규칙을 따릅니다.

  1. 기본적으로 거부. 하나 이상의 permit 정책이 일치하는 경우에만 트랜잭션이 허용됩니다. 시행된 정책이 없으면 모든 트랜잭션이 거부됩니다.
  2. 금지가 우선 적용됩니다. forbid 정책이 일치하면 permit 정책도 일치하더라도 트랜잭션이 거부됩니다.
  3. 평가에 실패한 정책은 일치하지 않습니다. 예를 들어 트랜잭션에 없는 선택적 컨텍스트 속성을 읽는 정책은 평가에 실패합니다. 인스턴스는 오류를 기록하고 해당 정책을 건너뛰고 나머지 시행된 정책으로 결정합니다. 이는 forbid 정책에도 적용되므로 누락된 속성에서 실패할 수 없는 forbid 정책을 작성합니다. 예시를 보려면 시나리오 8 및 시나리오 9를 참조하세요.

여러 전송이 포함된 트랜잭션(예: 여러 전송 명령어가 있는 Solana 트랜잭션)은 각 전송에 대해 한 번씩 평가됩니다. 트랜잭션은 모든 전송이 허용되는 경우에만 허용됩니다. 전송이 거부되거나 디코딩할 수 없는 경우 전체 트랜잭션이 거부됩니다.

각 평가, 허용 또는 거부는 Transaction.policyEvaluationRecord의 트랜잭션에서 반환되는 평가 레코드를 생성합니다.

이 결정에 따라 인스턴스가 더 많은 서명자를 기다리지 않고 트랜잭션에 서명할 수 있는지 여부가 제어됩니다.

  • PERMIT: CreateTransaction 요청에 이미 키링의 키 정책을 충족하기에 충분한 서명자 승인이 포함된 경우 트랜잭션이 즉시 SIGNING로 이동합니다. 그렇지 않으면 PENDING_AUTHORIZATION에 생성되고 더 많은 서명자를 기다립니다.
  • DENY: 인스턴스가 트랜잭션에 자동으로 서명하지 않습니다. 트랜잭션은 PENDING_AUTHORIZATION에서 생성되며 policyEvaluationRecord.decision는 DENY로 설정됩니다. 서명자는 평가 기록을 검토하고 트랜잭션을 거부 (DENY를 사용한 RecordSignerDecision)하거나 승인 (AUTHORIZE)할 수 있습니다. 트랜잭션은 키 정책을 충족하기에 충분한 서명자가 승인한 경우에만 서명됩니다.

트랜잭션 정책은 자동 서명에 대한 가드레일이며 서명자를 차단하지 않습니다. 서명자는 정책에서 거부하는 트랜잭션을 승인할 수 있습니다. 원래 PolicyEvaluationRecord는 감사를 위해 트랜잭션에 연결된 상태로 유지됩니다.

정책 수명 주기

거래 정책은 변경할 수 없습니다. TransactionPolicy에는 업데이트 메서드가 없으며 rule는 변경할 수 없습니다. 규칙을 변경하려면 DisableTransactionPolicy를 사용하여 정책을 사용 중지하고 CreateTransactionPolicy를 사용하여 새 정책을 만듭니다.

정책을 활성화하거나 사용 중지하려면 정책 작성자 (User.roleStatuses에서 활성 POLICY_AUTHOR 역할이 있는 사용자)의 정족수 승인이 필요합니다. 각 정책 작성자는 정책 (또는 CreateTransactionPolicy의 경우 인스턴스), 작업(ACTIVATE 또는 DISABLE), rule.cedarDocument의 이름을 지정하는 TransactionPolicySigningPayload에 서명합니다. 변경을 제안하는 요청은 첫 번째 승인으로 계산됩니다. 다른 정책 작성자는 ApproveTransactionPolicy로 승인합니다. 필요한 승인 수는 activationInfo.requiredApprovals 및 deactivationInfo.requiredApprovals에 있습니다. 인스턴스에 승인이 하나만 필요한 경우 변경사항이 즉시 적용됩니다.

다음 표에서는 각 정책 상태와 해당 상태의 정책이 시행되는지 여부를 설명합니다.

주 의미 적용 여부
PENDING_ACTIVE 정책이 제안되었으며 정책 작성자의 승인을 기다리는 중입니다. 없음
ACTIVE 정책에 승인이 activationInfo.requiredApprovals개 있습니다. 예
PENDING_DISABLED 정책 작성자가 정책을 사용 중지해 달라고 요청했으며 요청이 승인을 기다리고 있습니다. 예, 요청에 deactivationInfo.requiredApprovals개의 승인이 있을 때까지
DISABLED 정책이 사용 중지되었거나 활성화되기 전에 철회되었습니다. 사용 중지된 정책은 감사를 위해 보관됩니다. 없음

정책은 다음 상태를 한 방향으로 이동합니다.

  • PENDING_ACTIVE에서 ACTIVE: 활성화에 충분한 승인이 있습니다.
  • PENDING_ACTIVE에서 DISABLED: 정책 작성자가 활성화되기 전에 DisableTransactionPolicy를 사용하여 정책을 철회합니다.
  • ACTIVE~PENDING_DISABLED: 정책 작성자가 DisableTransactionPolicy를 호출합니다.
  • PENDING_DISABLED~DISABLED: 사용 중지 요청에 충분한 승인이 있습니다.

정책은 각 대기 중 상태에 최대 한 번만 진입합니다. 사용 중지된 정책은 다시 사용 설정할 수 없습니다. 대신 새 정책을 만드세요.

이러한 메서드를 호출할 수 있는 사용자는 사용자 역할을 참조하세요.

정책 세트 버전

정책 세트는 특정 시점에 시행되는 정책 세트 (ACTIVE 또는 PENDING_DISABLED)입니다. 활성화 또는 중지가 완료될 때마다 인스턴스는 해당 전환에 인스턴스 카운터의 다음 번호를 부여하고 activationInfo.transitionSequence 또는 deactivationInfo.transitionSequence에 기록합니다. 이 숫자는 전환으로 생성된 정책 세트 버전입니다.

다음 표에서는 일련의 이벤트에 따라 정책 세트 버전이 어떻게 변경되는지 보여줍니다.

이벤트 전환 시퀀스 시행된 정책
정책 A가 활성화됩니다. A: activationInfo.transitionSequence = 1 A
정책 B가 활성화됩니다. B: activationInfo.transitionSequence = 2 A, B
정책 C가 제안된 후 (PENDING_ACTIVE) 철회됩니다. 없음 A, B
정책 A에 대한 사용 중지 요청이 승인됩니다. A: deactivationInfo.transitionSequence = 3 B

PENDING_ACTIVE 정책을 철회해도 시행되는 정책 집합은 변경되지 않으므로 전환 시퀀스가 없고 정책 집합 버전이 변경되지 않습니다. 전환이 승인을 기다리는 동안 transitionSequence가 설정되지 않습니다.

각 평가는 트랜잭션의 createTime를 기준으로 정책, KeyList, 키를 읽고 당시 완료된 가장 높은 전환 시퀀스를 policyEvaluationRecord.policySetVersion에 기록합니다. 두 평가의 정책 세트 버전이 동일하면 동일한 정책을 사용한 것입니다.

Cedar 요청

Cedar 요청에는 주 구성원, 작업, 리소스, 컨텍스트가 있습니다. 예를 들면 다음과 같습니다.

permit (
  principal == User::"alice@example.com",
  action == Action::"buy_transaction",
  resource == Resource::"transaction_management"
)
when {
  context.principal_keyring == "institutional-treasury" &&
  context has fiat_amount && context.fiat_amount <= 10000
};

사용자가 Cedar 주 구성원에 매핑되는 방식

주 구성원은 트랜잭션의 개시자입니다. 즉, principal가 CreateTransaction 호출자의 인증된 ID와 일치하는 사용자입니다. 사용자에게 활성 SIGNER 역할이 있어야 합니다. Cedar에서 주 구성원은 ID가 사용자의 principal 필드인 User 항목입니다(예: User::"alice@example.com").

인스턴스는 Cedar에 항목 데이터를 전달하지 않습니다. User 항목에는 속성과 상위 항목이 없으므로 다음과 같습니다.

  • principal == User::"alice@example.com"는 Alice가 시작하는 트랜잭션과 일치합니다.
  • principal in Team::"treasury"가 일치하지 않습니다. 키로 서명할 수 있는 사용자를 제한하려면 KeyRing의 키 정책을 사용합니다. 키 그룹으로 규칙 범위를 지정하려면 context.principal_keyring를 선택합니다.
  • principal.team와 같은 principal의 속성을 읽는 규칙은 평가되지 않습니다.

사용자의 principal는 변경할 수 없으므로 주 구성원의 이름을 지정하는 규칙은 동일한 ID를 계속 참조합니다.

작업 및 리소스

  • action: Cedar Action 항목으로 형식이 지정된 CreateTransaction 요청의 Transaction.action 값입니다. CreateTransaction에는 다음 작업이 사용됩니다.

    작업 연결 대상:
    Action::"buy_transaction" 애셋을 획득하는 트랜잭션입니다.
    Action::"sell_transaction" 애셋을 처분하는 트랜잭션입니다.
    Action::"internal_transfer_transaction" 결제 또는 키 간 스윕과 같은 자산 전송입니다.

    작업을 시작한 사용자가 작업을 선택합니다. 다자간 계산은 페이로드에서 작업을 추론하지 않습니다. 규칙은 하나의 작업 (action == Action::"buy_transaction"), 작업 목록(action in [Action::"buy_transaction", Action::"sell_transaction"])과 일치하거나 action를 제한 없이 남겨두어 모든 작업과 일치할 수 있습니다.

  • resource: 트랜잭션 평가의 경우 항상 Resource::"transaction_management"입니다. 규칙은 resource == Resource::"transaction_management"를 확인하거나 resource를 제한되지 않은 상태로 둘 수 있습니다.

컨텍스트 속성

컨텍스트에는 정책에서 확인하는 속성이 포함됩니다. 이러한 데이터는 다음 두 가지 소스에서 가져옵니다.

  • 트랜잭션 페이로드 및 서명 키 인스턴스는 Transaction.payload를 디코딩하고 서명 키와 키링의 ID를 추가합니다. 이러한 속성은 principal_keyring, principal_key, blockchain, schema, secondary_key, amount_token_scaled, token_symbol, contract_address, chain_id, max_fee_atomic, payload, time_stamp입니다. 전체 표와 각 블록체인의 동작은 트랜잭션 정책 규칙 작성을 참조하세요.
  • 트랜잭션의 metadata 필드: 개시자가 CreateTransaction에서 설정합니다.

다음 표에서는 메타데이터 속성을 설명합니다.

Transaction.metadata 필드 Cedar 속성 삼나무 유형 값
fiatAmount context.fiat_amount Long 미국 달러 (google.type.Money)로 표시된 거래 가치입니다. currencyCode는 USD여야 하고, units는 0 이상이어야 하며, nanos는 0여야 합니다.
validity context.validity Long 트랜잭션이 유효한 기간(google.protobuf.Duration)(초 단위)입니다. 0초보다 길어야 하며 초 단위 이하는 허용되지 않습니다.
principalValue1 context.principal_value1 String 정의하는 값(최대 256자(영문 기준)), 예를 들어 트레이딩 데스크 또는 비용 센터입니다.
principalValue2 context.principal_value2 String 내부 티켓 또는 상대방 ID와 같이 최대 256자(영문 기준)까지 정의하는 값입니다.

메타데이터에는 다음 규칙이 적용됩니다.

  • 설정되지 않은 필드는 컨텍스트에 없습니다. 트랜잭션에 fiatAmount가 없으면 context.fiat_amount가 존재하지 않으며 이를 읽는 정책이 평가되지 않습니다. context has fiat_amount && context.fiat_amount <= 10000와 같이 먼저 has로 속성을 확인합니다.
  • 메타데이터가 잘못되면 요청이 실패합니다. 필드가 앞의 표에 있는 규칙을 위반하는 경우(예: EUR의 fiatAmount 또는 0이 아닌 nanos, 0초의 validity, 256자(영문 기준)를 초과하는 principalValue1) CreateTransaction가 INVALID_ARGUMENT와 함께 실패하고 정책이 평가되지 않습니다.
  • 인스턴스는 트랜잭션에 대해 메타데이터를 확인하지 않습니다. fiatAmount은 이니시에이터가 말하는 거래의 가치입니다. 다른 서명자는 승인하기 전에 Transaction.metadata 및 policyEvaluationRecord.evaluationContext에서 메타데이터를 확인합니다. 메타데이터와 별개로 온체인 금액을 제한하려면 context.amount_token_scaled 및 context.contract_address를 확인하세요.
  • 트랜잭션이 생성된 후에는 메타데이터를 변경할 수 없습니다.

키링

KeyRing은 키를 그룹화합니다. 모든 트랜잭션의 컨텍스트에는 principal_keyring 및 principal_key가 있으므로 나중에 생성된 키를 포함하여 키링의 모든 키에 규칙을 적용할 수 있으며 키링은 KeyList의 항목이 될 수 있습니다. 자세한 내용과 규칙 예시는 KeyRings을 참조하세요.

KeyLists

KeyList는 정책에서 참조할 수 있는 블록체인 주소의 이름이 지정된 목록입니다(예: 대상 허용 목록). 각 항목은 다음 중 하나입니다.

  • 수동 항목 (manualEntry): 인스턴스에서 관리하지 않는 주소로, 선택사항인 source 및 reason 필드가 있습니다.
  • 인스턴스의 키 (key): 키의 주소와 일치합니다.
  • 인스턴스의 KeyRing (keyRing): 항목이 추가된 후 생성된 키를 포함하여 KeyRing에 있는 모든 활성 키의 주소와 일치합니다.

정책이 승인된 후 KeyList가 변경될 수 있습니다. AddKeyListEntries 또는 RemoveKeyListEntries를 사용하여 항목을 추가하거나 삭제하면 KeyList를 참조하는 모든 정책이 새 정책 작성자 승인 없이 다음 평가의 새 항목을 사용합니다. PENDING_ACTIVE, ACTIVE 또는 PENDING_DISABLED 정책이 KeyList를 참조하는 동안에는 DeleteKeyList로 KeyList를 삭제할 수 없습니다.

Cedar 컨텍스트의 KeyList

평가 시 인스턴스는 각 KeyList를 String 블록체인 주소의 플랫 Set로 확장합니다. 즉, 수동 항목과 모든 키 및 KeyRing 항목에서 파생된 주소입니다. 각 집합은 Cedar에 context.key_lists["<var>KEY_LIST_ID</var>"]로 전달됩니다. 여기서 KEY_LIST_ID는 KeyList 리소스 이름의 {keyList} ID입니다(예: projects/my-project/locations/us-central1/instances/my-instance/keyLists/trusted-destinations의 경우 trusted-destinations).

규칙은 Cedar contains 연산자를 사용하여 디코딩된 대상 주소 context.secondary_key에 대해 멤버십을 테스트합니다. 예를 들어 trusted-destinations KeyList의 주소로만 전송을 허용하려면 다음 안내를 따르세요.

// Assuming you created a KeyList with ID "trusted-destinations":
permit (principal, action, resource)
when { context.key_lists["trusted-destinations"].contains(context.secondary_key) };

blocked-addresses KeyList의 주소로의 전송을 거부하려면 다음 안내를 따르세요.

// Assuming you created a KeyList with ID "blocked-addresses":
forbid (principal, action, resource)
when { context.key_lists["blocked-addresses"].contains(context.secondary_key) };

다음 사항에 유의하세요.

  • KeyList ID에는 점 문법이 아닌 대괄호 문법을 사용합니다. ID에 하이픈이 포함되어 있으면 Cedar의 점 문법 (context.key_lists.trusted-destinations)이 파싱되지 않습니다. Cedar는 하이픈을 빼기로 읽거나 서버에서 생성된 UUID처럼 숫자로 시작합니다. 대괄호 문법 context.key_lists["<var>KEY_LIST_ID</var>"]는 모든 ID에 적용됩니다.
  • key_lists는 항상 존재하며 규칙은 이 키 목록을 직접 읽을 수 있습니다. CreateTransactionPolicy는 규칙이 참조하는 모든 KeyList가 존재하는지 확인하고, 정책이 KeyList를 참조하는 동안에는 DeleteKeyList가 KeyList 삭제를 거부합니다. 규칙이 아직 존재하지 않을 수 있는 KeyList를 참조하는 경우에만 context.key_lists has "<var>KEY_LIST_ID</var>"를 사용합니다.
  • 주소는 문자열로 비교됩니다. secondary_key는 트랜잭션 정책 규칙 작성에서 각 블록체인에 대해 설명하는 형식을 사용합니다(예: 이더리움의 경우 대소문자 혼합 EIP-55 체크섬 형식). 동일한 형식으로 수동 항목을 추가합니다.
  • Solana 토큰 전송의 secondary_key는 소유자의 지갑이 아닌 대상 토큰 계정입니다. 지갑을 허용하려면 허용하는 각 민트에 대해 토큰 계정을 추가합니다.

각 평가는 정책과 동시에 트랜잭션의 createTime에서 KeyList 멤버십을 확인하고 결과를 policyEvaluationRecord.keyListMemberships에 기록합니다. KeyList, 테스트된 주소, 멤버인지 여부, 일치하는 항목입니다.

KeyList는 정책에서 허용하는 항목을 변경하므로 변경할 수 있는 사용자를 제한하세요. KeyList 메서드에는 roles/mpc.admin가 필요합니다. 자세한 내용은 IAM 권한을 참조하세요.

거부 이유

policyEvaluationRecord.decision가 DENY인 경우 policyEvaluationRecord.denyReason에 이유가 표시됩니다. 다음 표에서는 각 거부 이유를 설명합니다.

거부 이유 일시 정책 결정
FORBID_RULE_MATCHED 시행된 forbid 정책이 하나 이상 일치했습니다. 일치하는 forbid 정책입니다.
NO_PERMIT_RULE_MATCHED 페이로드가 디코딩되었고, 일치하는 forbid 정책이 없고, 평가에 실패한 정책이 없고, 일치하는 permit 정책이 없습니다. 없음
EVALUATION_ERROR 일치하는 permit 또는 forbid 정책이 없고, 예를 들어 컨텍스트에 없는 선택적 속성을 읽기 때문에 하나 이상의 정책을 평가할 수 없습니다. 없음 evaluationErrors는 오류를 나열합니다.
UNRECOGNIZED_PAYLOAD 인스턴스가 Transaction.payload를 디코딩하거나 컨텍스트에 투영할 수 없습니다. 예를 들어 잘못된 형식의 바이트, 지원되지 않는 명령어 또는 계약 작업, 수신자가 여러 명인 비트코인 트랜잭션 때문일 수 있습니다. 정책이 평가되지 않습니다. 없음 evaluationErrors에 파서 오류가 표시됩니다.

이유는 다음 순서로 결정됩니다.

  1. 페이로드를 디코딩하거나 컨텍스트에 투영할 수 없는 경우 결정은 UNRECOGNIZED_PAYLOAD와 함께 DENY입니다.
  2. 그렇지 않으면 시행된 모든 정책이 평가됩니다. forbid 정책이 일치하면 permit 정책도 일치하거나 다른 정책을 평가하지 못하더라도 FORBID_RULE_MATCHED와 함께 DENY로 결정됩니다.
  3. 그렇지 않고 permit 정책이 하나 이상 일치하면 결정은 PERMIT입니다. 다른 정책의 오류는 계속 evaluationErrors에 기록됩니다.
  4. 그렇지 않으면 평가에 실패한 정책이 있는 경우 결정은 EVALUATION_ERROR과 함께 DENY이고, 일치하지 않고 평가된 모든 정책이 있는 경우 NO_PERMIT_RULE_MATCHED입니다.

결정이 PERMIT인 경우에도 오류가 기록되므로 항상 실패하여 일치하지 않는 정책의 평가 기록을 확인하세요.

시나리오

시나리오 1~9에서 앨리스(User::"alice@example.com")는 action가 Action::"internal_transfer_transaction"로 설정된 유효한 이더리움 전송과 이 메타데이터를 만듭니다(시나리오에 달리 명시되지 않는 한).

"metadata": {
  "fiatAmount": {"currencyCode": "USD", "units": "5000"},
  "principalValue1": "treasury-desk"
}

트랜잭션에 validity 및 principalValue2가 없습니다.

다음 표에는 각 시나리오가 요약되어 있습니다.

시나리오 시행된 정책 또는 페이로드 결정 거부 이유
1 없음 DENY NO_PERMIT_RULE_MATCHED
2 일치하는 permit 1개 PERMIT
3 일치하지 않는 permit 1개 DENY NO_PERMIT_RULE_MATCHED
4 permit 2개, 일치하는 항목 1개 PERMIT
5 일치하는 permit 및 forbid DENY FORBID_RULE_MATCHED
6 누락된 속성을 읽는 permit DENY EVALUATION_ERROR
7 has님과 함께한 permit DENY NO_PERMIT_RULE_MATCHED
8 누락된 속성을 읽는 forbid 및 일치하는 permit PERMIT
9 속성이 필요한 forbid DENY FORBID_RULE_MATCHED
10 디코딩할 수 없는 페이로드 DENY UNRECOGNIZED_PAYLOAD

시나리오 1: 시행된 정책 없음

인스턴스에 ACTIVE 또는 PENDING_DISABLED 정책이 없습니다.

결정: DENY, NO_PERMIT_RULE_MATCHED 일치하는 permit 정책이 없으면 모든 트랜잭션이 거부됩니다. 새 인스턴스에서는 정책 작성자가 permit 정책을 활성화할 때까지 트랜잭션이 자동으로 서명되지 않습니다. 서명자가 각 트랜잭션을 승인해야 합니다.

시나리오 2: 일치하는 허가 1개

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 10000 };

결정: PERMIT. 금액 5,000은 10,000 이하입니다. determiningPolicyIds에 이 정책이 나열되어 있습니다.

시나리오 3: 일치하지 않는 허가증 1개

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 1000 };

결정: DENY, NO_PERMIT_RULE_MATCHED 금액 5,000은 1,000보다 크며 다른 정책은 트랜잭션을 허용하지 않습니다.

시나리오 4: 허가 2개, 일치하는 항목 1개

정책 A:

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 1000 };

정책 B:

permit (
  principal == User::"alice@example.com",
  action == Action::"internal_transfer_transaction",
  resource == Resource::"transaction_management"
)
when {
  context has fiat_amount && context.fiat_amount <= 25000 &&
  context has principal_value1 && context.principal_value1 == "treasury-desk"
};

결정: PERMIT. 정책 A는 일치하지 않지만 정책 B는 일치합니다. 일치하는 permit 정책 하나로 충분합니다. determiningPolicyIds에는 정책 B만 나열됩니다.

시나리오 5: 금지가 허용을 재정의함

정책 A:

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 10000 };

정책 B:

forbid (principal, action, resource)
when { context has principal_value1 && context.principal_value1 == "treasury-desk" };

결정: DENY, FORBID_RULE_MATCHED 두 정책이 모두 일치하고 forbid이 적용됩니다. determiningPolicyIds에는 정책 B만 나열됩니다.

시나리오 6: 허가에서 누락된 속성 읽기

permit (principal, action, resource)
when { context.validity <= 3600 };

결정: DENY, EVALUATION_ERROR 트랜잭션에 validity가 없으므로 context.validity가 존재하지 않으며 정책이 평가되지 않습니다. 다른 정책은 트랜잭션을 허용하지 않습니다. evaluationErrors에 오류가 표시됩니다.

시나리오 7: 동일한 권한,

permit (principal, action, resource)
when { context has validity && context.validity <= 3600 };

결정: DENY, NO_PERMIT_RULE_MATCHED context has validity가 false이므로 정책은 실패하는 대신 false로 평가됩니다. 트랜잭션은 여전히 거부되지만 정책이 평가되었고 일치하지 않는다는 이유가 표시됩니다.

시나리오 8: 금지에서 누락된 속성 읽기

정책 A:

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 10000 };

정책 B:

forbid (principal, action, resource)
when { context.principal_value2 == "sanctioned-counterparty" };

결정: PERMIT. 트랜잭션에 principalValue2가 없으므로 정책 B가 평가되지 않고 건너뜁니다. 정책 A가 일치합니다. determiningPolicyIds는 정책 A를 나열하고 evaluationErrors는 정책 B의 오류를 나열합니다.

시나리오 9: 속성이 필요한 금지

정책 A는 시나리오 8의 permit 정책입니다. 정책 B:

forbid (principal, action, resource)
unless { context has fiat_amount };

결정: fiatAmount가 있는 이러한 시나리오의 트랜잭션에 대한 PERMIT입니다. Alice가 fiatAmount를 생략하면 결정은 DENY입니다. FORBID_RULE_MATCHED: context has fiat_amount는 false이므로 forbid 정책이 일치합니다. 이 정책은 has만 사용하므로 평가에 실패할 수 없습니다.

필수 속성을 하나의 forbid 정책에서 해당 값에 대한 검사와 결합하려면 먼저 속성을 확인합니다.

forbid (principal, action, resource)
unless { context has fiat_amount && context.fiat_amount <= 10000 };

시나리오 10: 디코딩할 수 없는 페이로드

앨리스는 Transaction.schema의 파서로 payload를 디코딩할 수 없는 트랜잭션을 만듭니다(예: 잘린 RLP 바이트, 수신자가 여러 명인 비트코인 PSBT, 지원되지 않는 명령어가 있는 Solana 트랜잭션).

결정: DENY, UNRECOGNIZED_PAYLOAD 정책이 평가되지 않습니다. evaluationErrors는 파서 오류를 나열하고 determiningPolicyIds는 비어 있습니다.

평가 기록

각 평가는 변경할 수 없는 PolicyEvaluationRecord을 생성합니다. Transaction.policyEvaluationRecord로 반환되며 다음 필드가 있습니다.

필드 값
decision PERMIT 또는 DENY.
denyReason 거부 사유 중 하나입니다. 결정이 PERMIT인 경우 설정 해제됩니다.
determiningPolicyIds PERMIT에 일치한 permit 정책의 ID입니다. FORBID_RULE_MATCHED에 일치한 forbid 정책의 ID입니다. 그 외의 경우에는 비어 있습니다.
evaluationErrors 평가에 실패한 정책의 오류 또는 denyReason가 UNRECOGNIZED_PAYLOAD인 경우 파서 오류입니다.
evaluationContext 정책이 평가된 Cedar 컨텍스트입니다(google.protobuf.Struct). 64비트 정수는 정밀도를 유지하기 위해 십진수 문자열로 저장됩니다.
policySetVersion 평가에 사용된 정책 세트 버전입니다.
keyListMemberships 평가 중에 확인된 KeyList 멤버십입니다.
intentDigest 평가된 트랜잭션 페이로드의 소문자 16진수 인코딩 다이제스트입니다. 해시는 페이로드의 스키마에 따라 달라집니다. ETHEREUM_TX_V2의 경우 트랜잭션의 Keccak-256, BITCOIN_TX_V2의 경우 첫 번째 입력의 sighash, SOLANA_TX_V1의 경우 서명되지 않은 메시지의 SHA-256, EIP712_TYPED_DATA_V1의 경우 EIP-712 서명 다이제스트 keccak256(0x1901 ++ domainSeparator ++ hashStruct(message))입니다.
evaluationTime 평가가 실행된 시간입니다.