11. Cosigner & Callback Handler
Stage 24 정식 명세 · 5 auth option · /v2 URL · key model 비대칭Cosigner 종류
| 종류 | 위치 | SGX 강제 |
|---|---|---|
| Mobile Co-Signer | User mobile device (iOS Keychain / Android TEE) | device-level enclave |
| API Co-Signer | Customer-deployed SGX server | SGX baseline (Stage 8 ANSWERED) |
| Fireblocks Cloud Co-Signers (2) | Azure SGX (3-5 machines, segregated network) | YES |
| Fireblocks Communal Test Co-signer | Fireblocks 공유 (testnet 전용) | — |
Chain of Trust
Co-Signer Certificate (self-generated, priv → Configuration DB)
↓ (CSR via Co-Signer Broker)
Core Services Intermediate Certificate (built into image)
↓ (sign)
Co-Signer End Certificate (배포)
Callback Handler — Optional 성격 (★ 보안 신호)
Default = Auto-Sign (★ Risk)
create-api-co-signer-callback-handler.md 직접 인용:
"If a Callback Handler is not configured for an API user, the Co-signer will automatically sign or approve all requests it receives for that API user."
→ Callback Handler 미설정 = Co-signer 자동 승인/서명. 외부 business / compliance 검증 bypass 가능 — Risk register 등재.
5 Authentication Options (★ Stage 24 ANSWERED)
| # | 명칭 | Message | TLS | Version | SGX only |
|---|---|---|---|---|---|
| 1 | Public key authentication | JWT (RSA 2048) | HTTPS + trusted CA (prod) | all | — |
| 2 | Self-Signed Cert pinning | JSON | TLS cert pin | all | — |
| 3 | Root-CA Cert | JSON | TLS Root-CA validation | v2025.12.11+ | — |
| 4 | Hybrid — Public key + Cert pin | JWT | TLS cert pin | v2025.12.11+ | ★ SGX only |
| 5 | Hybrid — Public key + Root-CA | JWT | TLS Root-CA | v2025.12.11+ | ★ SGX only |
Hybrid options (4/5) = message-layer (JWT 서명) + TLS-layer (cert) dual security.
Payload / URL Convention
- Endpoints:
tx_sign_request+config_change_sign_request(Co-signer → Callback Handler POST) - /v2 URL 분기:
- JWT-bearing (1, 4, 5):
https://<base>/v2/tx_sign_request - JSON-bearing (2, 3):
https://<base>/tx_sign_request(no /v2 prefix)
- JWT-bearing (1, 4, 5):
- URL setting 시 base URL + custom relative path 만 입력 — /v2/... 는 자동 추가
- Production = HTTPS w/ trusted CA cert 강제 권장 / dev = HTTP 허용
Key Model 비대칭 (★ architectural 신호)
| 키 | 범위 | 비고 |
|---|---|---|
| Co-signer private key | global — 해당 Co-signer 에 페어링된 모든 API user 의 request 서명에 재사용 | "The same Co-signer private key is used to sign request messages... for all API users paired with this Co-signer." |
| Callback Handler private key | per-API-user — API user 별 별도 public key 를 Co-signer 에 등록 | RSA 2048 only (response auth) |
→ Co-signer 측 single global key compromise = 모든 API user 의 request 서명 위조 가능. Callback Handler 측 key 는 per-user 격리.
Pairing / Re-enroll
- Pairing token 1시간 유효
- Callback Handler SSL public key pinning — Co-signer 가 cert 고정 신뢰
- Re-enroll 요구: (a) auth method 전환, (b) SSL 인증서 변경 또는 만료 — 둘 다 Owner 의 key share 승인 필요
DB Schema
CREATE TABLE cosigner_configs (
id BINARY(16) PRIMARY KEY,
workspace_id BINARY(16) NOT NULL,
paired_api_user_id BINARY(16), -- API Co-signer 의 경우
type ENUM('mobile', 'api-sgx', 'communal-test', 'fb-cloud-sgx') NOT NULL,
end_cert_pem TEXT NOT NULL,
end_cert_fingerprint BINARY(32) NOT NULL,
intermediate_cert_id BINARY(16) NOT NULL, -- chain of trust
configuration_db_keyref VARCHAR(128), -- private key reference (HSM)
registered_at DATETIME(6) NOT NULL,
re_enrolled_at DATETIME(6),
UNIQUE KEY (end_cert_fingerprint)
);
CREATE TABLE callback_endpoints (
id BINARY(16) PRIMARY KEY,
cosigner_id BINARY(16) NOT NULL,
paired_api_user_id BINARY(16) NOT NULL, -- per-API-user key model
url_base VARCHAR(255) NOT NULL,
custom_path VARCHAR(128),
auth_option TINYINT NOT NULL, -- 1 ~ 5
jwt_or_json ENUM('jwt', 'json') NOT NULL,
url_uses_v2 BOOLEAN NOT NULL,
callback_pubkey BLOB NOT NULL, -- RSA 2048 public
tls_pin_sha256 BINARY(32), -- option 2, 4 의 cert pin
registered_at DATETIME(6) NOT NULL,
last_invoked_at DATETIME(6)
);
-- Optional 검증 endpoint — 없으면 auto-sign default 적용 (★ Risk)
CREATE TABLE designated_signers (
id BINARY(16) PRIMARY KEY,
policy_rule_id BINARY(16) NOT NULL,
signer_user_id BINARY(16),
signer_user_group_id BINARY(16),
internal_exchange_excluded BOOLEAN NOT NULL DEFAULT TRUE,
KEY (policy_rule_id)
);