Mutual TLS 대 애플리케이션 계층 핸드셰이크: 에이전트 네트워크에서 '이 피어는 누구인가?'에 답하는 두 가지 방법
요약
에이전트 네트워크에서 피어 인증을 구현하는 두 가지 방식인 mTLS와 애플리케이션 계층 핸드셰이크를 비교합니다. 수명이 짧은 에이전트 환경에서는 mTLS의 복잡성과 지연 시간 문제로 인해 애플리케이션 계층에서의 신원 증명이 더 효율적일 수 있음을 설명합니다.
핵심 포인트
- mTLS는 전송 계층에서 신원을 증명하며 PKI 인프라가 필요함
- 애플리케이션 계층 핸드셰이크는 암호화 터널 구축 후 상위 계층에서 인증 수행
- 수명이 짧은 에이전트(ephemeral agents)에게 mTLS는 오버헤드가 큼
- 에이전트 스웜 환경에서는 신원 교환과 전송 계층의 분리가 유리함
지난주 저는 친구가 노드가 재활용될 때 왜 자신의 에이전트 스웜(agent swarm)이 인증에 계속 실패하는지 디버깅하는 것을 도왔습니다. 에이전트가 다운되었다가 새로운 컨테이너 IP로 돌아올 때마다 mutual TLS 핸드셰이크가 무너졌습니다. 만료된 인증서, 취소된 중간 인증서(intermediates), 아무도 알아채지 못한 채 로테이션된 루트 CA, 그리고 유명한 '인증서가 47개나 있는데 어떤 서비스와 연결되는지 확신할 수 없다'는 문제까지요.
근본적인 질문은 간단합니다. 이 피어는 누구인가? 이 질문에 답하기 위해 근본적으로 다른 두 가지 아키텍처가 존재합니다:
- Mutual TLS (mTLS) — 애플리케이션 데이터 바이트 하나가 흐르기 전에 전송 계층(transport layer)에서 신원을 증명합니다.
- 애플리케이션 계층 핸드셰이크(Application-layer handshake) — 먼저 터널을 설정한 다음, 명시적인 승인/거부(approve/reject)를 통해 애플리케이션 계층에서 인증합니다.
이 중 하나는 PKI 팀을 보유하고 장기간 운영되는 서비스에 잘 작동합니다. 다른 하나는 몇 분마다 나타났다 사라지는 일회성 에이전트(ephemeral agents)에 적합합니다. 이 둘은 대체재가 아니라, 서로 다른 문제에 대한 해결책입니다.
mTLS가 실제로 요구하는 것
- 인증 기관 (Certificate Authority, CA) 또는 cert-manager나 Smallstep과 같은 CA-as-a-service.
- 모든 피어(peer)가 다른 모든 피어의 발행자(issuer)를 인식할 수 있도록 루트 인증서(root certs, 또는 고정된 세트)를 배포하는 메커니즘.
- 폐기 관리 체계 (CRL 또는 OCSP stapling) — 대부분의 에이전트 배포 환경에서는 너무 무겁기 때문에 이를 생략합니다.
- 인증서가 만료되기 전에 실행되는 재발급 파이프라인 — 이는 배포 환경이 갱신될 수 있을 만큼 충분히 오래 유지되어야 함을 의미합니다.
12분 동안 유지되는 Kubernetes의 포드(pod)가 TLS 핸드셰이크(handshake)에 0.5초를 쓰고, OCSP 응답을 가져오는 데 30초를 소비하는 것은 터무니없습니다. 인증서 체인(cert chain)은 근본적으로 일시적인(transient) 상호작용에 지연 시간(latency)과 복잡성을 더합니다.
애플리케이션 계층의 대안
다른 접근 방식은 다음과 같습니다: 먼저 원시 암호화 터널(raw encrypted tunnel)을 엽니다. 어떤 보안 전송 방식(noise protocol, 단순한 X25519 키 교환, 사전 공유 대칭 키 등 피어들이 합의한 방식)이든 상관없습니다. 그 다음, "이 피어를 신뢰해야 하는가?"라고 묻고 사람이나 정책 객체(policy object)가 답변하게 함으로써 애플리케이션 계층에서 인증을 수행합니다.
외부에서 본 흐름은 다음과 같습니다:
Peer A Peer B
| |
|--- connect --------->|
...
신원 교환(identity exchange)은 전송 계층(transport)과 분리됩니다. 터널은 임시 키(ephemeral key)를 사용하여 즉시 설정될 수 있습니다. 신원 증명은 더 높은 계층에서 이루어지며, "승인"은 저장된 결정이 됩니다. 즉, 명시적으로 거부될 때까지 해당 피어는 신뢰 상태를 유지합니다.
에이전트에게 mTLS가 한계에 부딪히는 지점
왔다 갔다 하는 에이전트들에게 mTLS가 주는 고충은 다음과 같습니다:
짧은 수명. 단 하나의 추론(inference) 작업을 수행하고 종료되는 컨테이너는 인증서 갱신 루프를 유지할 수 없습니다. 각 실행 시마다 유효한 인증서가 필요하며, 이는 부팅 시마다 인증서를 발급하거나(시작 시 수 초가 추가됨), 에이전트가 접근할 수 있는 어딘가에 장기 유지 인증서를 저장해야 함을 의미합니다(이는 신뢰 모델을 깨뜨립니다 — 인증서가 배포 환경보다 더 오래 지속되기 때문입니다).
안정적인 신원(Identity)의 부재. mTLS는 신원을 인증서의 Subject 또는 SAN (Subject Alternative Name)에 결합합니다. 에이전트가 새로운 인증서와 함께 재시작되면, 동일한 에이전트 코드가 실행 중이더라도 이는 서로 다른 신원이 됩니다. 공개 키(Public Key)를 핀닝(Pinning)하지 않는 한 "이 피어(Peer)를 이전에 봤던 대상으로 인식한다"라고 말할 방법이 없으며, 이 시점에는 본질적으로 애플리케이션 계층의 신원 확인 기능을 직접 구현한 것이나 다름없습니다.
UDP 환경에서의 인증서 폐기 확인. mTLS의 OCSP (Online Certificate Status Protocol) 및 CRL (Certificate Revocation List) 메커니즘은 TCP 연결성과 응답자(Responder)와의 왕복(Round-trip)을 전제로 합니다. 손실이 잦거나 간헐적인 네트워크(에이전트가 주로 작동하는 환경)에서 CRL을 가져오는 작업은 지연 시간(Latency)을 추가하고 새로운 장애 모드(Failure mode)를 유발합니다.
암묵적인 신뢰 결정. mTLS에서는 인증서 체인이 검증되면 피어를 신뢰하게 됩니다. "내가 정말로 이 피어가 내 엔드포인트에 접근하는 것을 원하는가?"라고 물을 기회가 없습니다. 인증은 이진적(Binary)이며 전송 계층(Transport-level)에서 이루어집니다. 체인 내 어디에서든 CA (Certificate Authority)가 침해되면 모든 피어 관계가 침해됩니다.
명시적인 피어별 승인이 제공하는 이점
명시적 승인을 포함하는 애플리케이션 계층 핸드셰이크(Application-layer handshake)는 신뢰 모델을 "유효한 인증서를 가지고 있음을 증명하라"에서 "당신이 주장하는 본인이 맞음을 증명하고, 또한 누군가가 당신의 접속을 허용하기로 결정했음을 증명하라"로 변화시킵니다.
이는 에이전트 네트워크에서 중요한 몇 가지 이점을 제공합니다:
재시작 시에도 유지되는 신원. 피어의 신원은 CA 정책에 묶인 수명을 가진 인증서가 아니라, 장기 유지되는 공개 키(Public Key) 또는 해시(Hash)입니다. 에이전트가 재부팅될 때 동일한 신원을 제시하거나, 사람이 다시 승인할 수 있는 새로운 신원을 제시합니다. 관계는 현재의 TLS 컨텍스트가 아닌 에이전트 자체와 맺어집니다.
지연된 신뢰 (Deferred trust). 아직 아무도 에이전트 A를 승인하지 않았더라도, 에이전트 A는 에이전트 B에 연결할 수 있습니다. 터널은 생성되고 전송 계층은 암호화되지만, B(또는 B의 운영자)가 "네, 이 피어를 알고 있습니다"라고 말하기 전까지는 어떤 애플리케이션 데이터도 흐르지 않습니다. 이는 mTLS에서는 불가능합니다. mTLS에서는 인증서가 없거나 유효하지 않으면 전송 계층 자체가 열리지 않기 때문입니다.
즉각적이고 세밀한 폐기 (Revocation). CRL (Certificate Revocation List)을 게시하고 피어(peer)가 이를 가져올 때까지 기다리는 대신, 단순히 귀하의 측에서 해당 피어의 승인을 취소하면 됩니다. 터널은 암호화된 상태로 유지되지만 데이터 흐름은 중단됩니다. OCSP (Online Certificate Status Protocol), 전파 지연, 인프라가 필요 없습니다.
휘발성 노드 (Ephemeral nodes)에 더 가벼움. 인증서 갱신, 루트 저장소 (root-store) 관리, 접속해야 할 OCSP 응답기(responder)가 필요 없습니다. 에이전트가 시작되어 연결하고, 자신의 신원을 제시하고, 승인을 기다린 뒤 작업을 수행합니다. 여러 번의 왕복(round-trip)이 필요한 TLS 협상(negotiation)에 인증서 검증과 CRL 가져오기까지 더해지는 대신, 단 세 번의 핸드셰이크(handshake) 메시지만으로 충분합니다.
여전히 mTLS를 선택해야 하는 경우
공정하게 말하자면, mTLS가 모든 시나리오에서 틀린 것은 아닙니다. 다음과 같은 경우에는 mTLS가 적합합니다:
- PKI (Public Key Infrastructure) 팀이 인증서 수명 주기를 관리하는 장기 실행 서비스 (Long-lived services).
- 이미 서비스 메시 (Service mesh, 예: Istio, Linkerd)를 운영 중인 환경 — 이 문맥에서 mTLS는 "공짜"나 다름없습니다.
- 통제 수단으로서 X.509 인증서 검증을 의무화하는 컴플라이언스 프레임워크.
질문은 귀하의 에이전트 네트워크가 Kubernetes 메시 (mesh)에 더 가까운지, 아니면 어디서든 연결되는 수많은 단기 실행 프로세스 (short-lived processes)의 군집에 더 가까운지입니다.
종합하자면
두 접근 방식은 동일한 질문에 대해 서로 다른 방식으로 답합니다. mTLS는 전송 계층 (transport layer)이 신원을 책임지게 하며 인증서 체인 (certificate chain)을 신뢰합니다. 애플리케이션 계층 핸드셰이크 (application-layer handshake)는 별도의 신뢰 계층이 책임을 지게 하며 명시적인 승인을 신뢰합니다.
만약 에이전트가 메시 (mesh) 상의 장기 실행 서비스라면, mTLS가 가장 저항이 적은 경로일 수 있습니다. 만약 에이전트가 생성되어 작업을 수행한 뒤 사라지거나, 서로 다른 클라우드, 노트북, 또는 NAT 뒤에서 연결된다면, 피어별 승인 (per-peer approve) 모델은 인증서 지옥 (cert hell)을 완전히 피할 수 있게 해줍니다.
명시적 핸드셰이크를 위한 코드는 더 짧기도 합니다. 피어가 공개 키 지문 (public key fingerprint)을 제시하면, 상대측에서 로컬 허용 목록 (allowlist)을 확인하거나 사람에게 요청을 보내고, 관계가 기록됩니다. CA (Certificate Authority)도, CRL도, "인증서가 만료되었으니 다시 배포하십시오"라는 메시지도 필요 없습니다.
Pilot Protocol을 통한 피어 핸드셰이크 (Peer Handshake)
pilotctl handshake <peer-address> "requesting trust for cooperative task"
pilotctl approve <peer-id> # 단 한 번의 명령으로, 취소될 때까지 영구적으로 유지
이것이 전체 루프의 전부입니다. 터널은 이미 암호화되어 있으며, 핸드셰이크는 인증서 체인 (Certificate Chain) 대신 결정 (Decision)을 통해 "이 피어는 누구인가?"라는 질문에 답할 뿐입니다.
90초 동안만 생존하는 에이전트에서 인증서 문제를 디버깅하고 있는 자신을 발견한다면, 애초에 mTLS (Mutual TLS)가 정말 필요했는지, 아니면 그저 한 피어가 다른 피어에게 "승인"을 해주기만을 원했던 것은 아닌지 자문해 보십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기