관리자 키 교체는 새 주소를 발표하는 것으로 끝나지 않는다. 새 주소에 필요한 역할을 부여하고 실제 제어 가능성을 시험한 뒤, 옛 주소의 owner·admin·proposer·executor 권한을 취소해야 한다. 프록시 관리자, timelock, 멀티시그, 각 계약의 역할이 분산돼 있으면 모든 대상의 전후 상태와 이벤트를 확인해야 완전한 회전으로 볼 수 있다.
새 키를 추가한 것과 옛 키를 폐기한 것은 다르다
키 회전은 보통 새 키 생성, 주소 검증, 역할 부여, 기능 시험, 옛 역할 취소, 키 자료 폐기의 순서로 진행된다. 새 주소가 owner 목록에 들어갔어도 옛 주소가 남아 있으면 공격 표면은 줄지 않는다. ‘교체 완료’라는 문장보다 현재 역할 조회 결과와 취소 이벤트가 더 강한 증거다.
OpenZeppelin의 Ownable은 owner가 관리 작업을 수행하며 ownership을 새 주소로 이전할 수 있는 구조다. AccessControl은 여러 역할을 여러 계정에 줄 수 있어 한 번의 ownership transfer만으로 모든 권한이 이동하지 않을 수 있다. 계약별로 owner(), hasRole(), ProxyAdmin 소유자와 timelock 역할을 확인한다.
새 열쇠가 작동한다는 사실보다 옛 열쇠가 더는 어떤 문도 열지 못한다는 사실이 회전 완료를 증명한다.
JOBCOIN 해설

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.
- 새 키를 추가한 것과 옛 키를 폐기한 것은 다르다
키 회전은 보통 새 키 생성, 주소 검증, 역할 부여, 기능 시험, 옛 역할 취소, 키 자료 폐기의 순서로 진행된다.
- 권한 지도를 먼저 만든다
프로토콜의 관리자 권한은 하나의 계약에만 있지 않을 수 있다.
- 기본 관리자 역할은 별도로 경계한다
AccessControl의 관리자 역할은 다른 역할을 부여·취소할 수 있어 일반 운영 역할보다 강하다.
AI로 제작한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.
권한 지도를 먼저 만든다
프로토콜의 관리자 권한은 하나의 계약에만 있지 않을 수 있다. 토큰 mint·pause, 프록시 upgrade, 오라클 설정, 금고 이동, timelock 제안·실행, Safe 모듈 관리가 서로 다른 주소에 배정된다. 공지 대상이 ‘admin key’ 하나라고 해도 실제 역할 그래프를 그려야 빠진 권한을 찾을 수 있다.
AccessManager처럼 중앙 역할 관리 계약을 쓰는지, 각 계약이 AccessControl을 독립적으로 쓰는지에 따라 조회 방식이 다르다. OpenZeppelin 문서는 복수 계약에서 권한을 따로 추적하면 복잡성이 커지며 AccessManager가 역할과 대상 함수를 한 곳에서 관리할 수 있다고 설명한다.
| 대상 | 새 키 증거 | 옛 키 폐기 증거 |
|---|---|---|
| Ownable 계약 | OwnershipTransferred의 newOwner | owner()가 옛 주소가 아님 |
| AccessControl 역할 | RoleGranted와 hasRole=true | RoleRevoked와 hasRole=false |
| ProxyAdmin | 새 owner와 시험된 업그레이드 권한 | 옛 owner의 호출 실패 |
| Timelock | proposer·executor·admin 갱신 | 임시 관리자 renounce 또는 revoke |
| 멀티시그 | 새 owner·threshold 상태 | 옛 owner 제거 이벤트 |
기본 관리자 역할은 별도로 경계한다
AccessControl의 관리자 역할은 다른 역할을 부여·취소할 수 있어 일반 운영 역할보다 강하다. 키 회전에서 업무 역할만 새 주소로 옮기고 DEFAULT_ADMIN_ROLE이 옛 주소에 남으면 옛 키가 다시 권한을 만들 수 있다. 각 역할의 admin role 관계를 읽는다.
단일 EOA에서 멀티시그나 timelock으로 옮기는 회전은 보안 가정을 바꾼다. 다만 새 시스템의 owner·threshold·지연 설정이 잘못되면 실행 불능이나 우회 권한이 생길 수 있다. 대상 주소가 계약인지 확인하고 내부 통제 구조를 검증한다.
공개 전에 소유 증명과 복구 시험을 한다
공격자가 가짜 새 주소를 퍼뜨릴 수 있으므로 기존 관리자 권한으로 새 주소를 등록하는 온체인 거래와 공식 서명 메시지를 연결한다. 새 키가 하드웨어 또는 MPC에서 생성됐다면 공개 가능한 범위에서 생성·백업·승인자 분리 절차를 설명한다. 개인키 자체는 공개하거나 기사에 입력하지 않는다.
실제 권한 이전 전에 테스트넷이나 제한된 함수로 서명·승인·지연·실행을 검증한다. 복구 키가 있다면 평상시 사용 권한과 분리하고 사용 조건을 문서화한다. 키 손실을 막는다는 이유로 여러 운영자가 같은 시드 사본을 갖게 하면 독립성은 오히려 낮아진다.
- 모든 계약과 역할의 권한 지도를 만든다
- 기존 권한으로 새 주소 소유를 온체인에서 연결한다
- 새 키의 서명·멀티시그·timelock 실행을 시험한다
- 옛 주소의 owner·role·module 권한을 모두 취소한다
- 이벤트와 현재 read 상태를 기준 블록과 함께 공개한다
timelock은 키 회전에도 지연을 적용할 수 있다
TimelockController는 관리 작업을 일정 시간 지연해 이용자가 검토하고 대응할 시간을 주는 장치다. OpenZeppelin 문서는 mint·freeze·upgrade 같은 강한 기능의 관리자 오용을 단순 접근제어만으로 막을 수 없어 지연이 보호 장치가 된다고 설명한다.
회전 거래가 timelock을 거친다면 schedule, delay 경과, execute 세 단계를 추적한다. 공지 시점에 예약만 됐다면 완료라고 쓰지 않는다. 긴급 상황에서 지연을 우회하는 별도 권한이 있다면 누가 어떤 조건으로 쓸 수 있는지도 확인한다.
회전 뒤 남은 권한을 다시 스캔한다
옛 주소를 알려진 모든 계약의 owner·role 목록과 Safe owner 목록에서 검색한다. 이벤트 기록만 보면 과거 부여가 나온 뒤 다른 경로로 재부여됐을 수 있으므로 현재 상태를 기준으로 한다. 프록시 구현이 바뀌며 새로운 역할이 추가됐는지도 살핀다.
공시에는 변경 이유를 유출 사고와 정기 회전으로 구분하고, 유출이 의심되면 옛 키가 수행한 최근 거래 검토 결과를 포함한다. 영향이 확인되지 않았다면 ‘피해 없음’ 대신 확인한 체인·기간·권한 범위를 명시한다. 이후 정기 재검증 날짜를 잡아 문서와 온체인 상태가 다시 벌어지지 않게 한다.
자주 묻는 질문
새 관리자 주소가 공개되면 회전이 끝난 건가요?
아니다. 새 권한의 온체인 부여와 기능 시험, 옛 주소의 모든 관련 권한 취소를 확인해야 한다.
ownership transfer 하나면 모든 관리자 권한이 이동하나요?
항상 그렇지 않다. AccessControl 역할, ProxyAdmin, timelock, 멀티시그·모듈이 별도로 남을 수 있다.
옛 개인키를 삭제했다는 공지를 믿으면 되나요?
키 자료 폐기는 온체인에서 증명하기 어렵다. 그래서 옛 주소 권한을 계약에서 제거한 현재 상태가 중요하다.
더 깊이 읽기
본문에서 다룬 개념과 확인 절차를 다음 글에서 이어서 살펴보세요.



