9. Policy & TAP Rules
Stage 10 정식 명세 · 2 component · 3 action · designated signer · DCCPPolicy = Primary Security Control
about-policies.md, p.1 직접 인용: "Policies are your primary security control in your workspace." Fireblocks 보안 모델의 first-class spine.
Policy Rule 의 2 Component (★ Stage 10)
- Parameters (= Scope): initiator / source / destination / asset 등 characteristic
- Actions: Allow / Approved by / Block (→ 15. Approval State)
Policy 종류 (3 평면 — Stage 6+10)
| 종류 | 역할 | 평가 시점 |
|---|---|---|
| Fireblocks Policies (TAP) | 일반 tx 단위 rule. 본 페이지 주 대상 | Step 6-7 (Policy Engine SGX) |
| Deposit Control and Confirmation Policy (DCCP) | blockchain confirmation 횟수 정책 (incoming + outgoing). Clear 전 = inflow/outflow state lock | Confirming → Completed transition trigger |
| AML Transaction Screening Policy | AML provider 통합. workspace-level default 가능 (fail-on-unknown vs pass-on-unknown) | Step 5b (Screening Service) |
Designated Signer 메커니즘 (★ NS 라벨)
Policy 가 특정 tx type 의 서명자를 지정 → MPC 키 없는 NSA / Editor 가 그 tx 타입을 initiate 가능.
- NSA: "can initiate transactions when the Policy assigns a designated signer"
- Editor: "can also initiate certain transactions if the Policy defines another user capable of signing as a designated signer for that transaction type"
- 적용 범위: NSA / Editor 는 internal exchange transfer 를 제외한 모든 tx 를 designated signer 흐름으로 initiate
Second Authorizer
Non-Signing Admin / Approver 를 두 번째 authorizer 로 정의 가능 (Owner의 책임에 명시).
User Group in Policy
- User group 으로 다중 사용자를 single rule 에 매핑 → team 변경 시 rule 수정 불필요
- Initiator + Approved by 양쪽에 user group 사용 가능
- Sub-quorum: "requires any two members of a user group called Management to approve" — rule-level N-of-M
변경 거버넌스
- Policy 변경: Q+O (Admin Quorum + Owner) 필수 —
user-roles.md, p.7 권한표 *Approve workspace policies / Policy changes* 행 - 관리권: Owner + Admin-level user (NSA 포함). Console 에서 작성, assigned approval group 이 변경 approve
- mobile app 승인: "Transaction Policy changes" 가 workspace settings 승인 항목에 명시 — 실제 승인은 mobile 에서
Premium Features
Raw Signing / Mint / Burn = premium feature, 별도 구매. Vault Structure Best Practices 의 Mint/Burn/Pause/Deploy/Upgrade segregated vault 권장과 정합.
Whitelist vs OTA — Policy 의 방어 차이
| Address path | Policy 의 역할 |
|---|---|
| Whitelisted address | Admin Quorum 가 address-level approval — Policy 는 추가 rule (cap, approver) 적용 |
| One-Time Address (OTA) | Address-level Admin Quorum 없음 — Policy 가 사실상 유일한 자동 방어선 (preselected user/group/vault, threshold approval) |
DB Schema
CREATE TABLE policies (
id BINARY(16) PRIMARY KEY,
workspace_id BINARY(16) NOT NULL,
policy_type ENUM('transfer', 'contract-call', 'approve', 'dccp', 'aml') NOT NULL,
version INT NOT NULL, -- monotonic
active_at DATETIME(6) NOT NULL, -- ★ set-once when activated
superseded_at DATETIME(6),
KEY (workspace_id, policy_type, version)
);
CREATE TABLE policy_rules (
id BINARY(16) PRIMARY KEY,
policy_id BINARY(16) NOT NULL,
rule_number INT NOT NULL, -- first-match ordering
parameters_cbor BLOB NOT NULL, -- initiator / source / destination / asset / amount
action ENUM('allow', 'approved_by', 'block') NOT NULL,
designated_signer_user_group_id BINARY(16), -- NS 흐름의 signer set
approvers_user_group_id BINARY(16), -- Approved by 의 group
approvers_threshold INT, -- sub-quorum N
time_window_seconds INT, -- velocity limit
cumulative_usd_cap DECIMAL(38, 2), -- velocity limit cap
UNIQUE KEY (policy_id, rule_number)
);
-- ★ append-only
CREATE TABLE policy_change_log (
id BINARY(16) PRIMARY KEY,
policy_id BINARY(16) NOT NULL,
prev_version INT,
new_version INT NOT NULL,
diff_cbor BLOB NOT NULL, -- rule add/remove/edit
changed_by_user_id BINARY(16) NOT NULL,
approved_by_quorum_request_id BINARY(16) NOT NULL, -- Q+O 의 approval_request
changed_at DATETIME(6) NOT NULL,
mobile_app_approval_sigs BLOB NOT NULL -- mobile 서명 집합
);
CREATE TABLE user_groups (
id BINARY(16) PRIMARY KEY,
workspace_id BINARY(16) NOT NULL,
name VARCHAR(64) NOT NULL
);
CREATE TABLE user_group_members (
group_id BINARY(16) NOT NULL,
user_id BINARY(16) NOT NULL,
PRIMARY KEY (group_id, user_id)
);
BLOCKED rule number
tx 가 BLOCKED status 도달 시 violated rule number 표시 — transactions.blocked_by_rule_id + blocked_by_rule_number 컬럼.