30화

중복 토큰의 원본은 외부 검토실에서만 열 수 있었다

증거분석관은 빠진 말을 듣는다 · 2026. 10. 27.

조회수 0

중복 토큰의 원본은 외부 검토실에서만 열 수 있었다. 회색실은 사건 내부의 물리 기록을 확보했지만, 토큰이 어느 서비스에서 어떻게 재발급됐는지는 아직 요약본에 머물러 있었다. 송주혁은 자신의 회사 계정 전체를 열지 않았고, 나리는 선배 기자의 수첩 원문을 공개하지 않았다. 사람의 선택이 자료의 경계를 만들고 있었다.

서진은 사건표를 네 묶음으로 나눴다. 약품 이동, 사진 생성, 토큰 재발급, 외부 정리 서비스 계약. 네 묶음이 한 사람의 행동이라고 가정하면 증거가 빨리 연결되지만, 하나라도 다른 주체라면 사건의 구조가 달라졌다.

민우는 외부 검토자와 함께 토큰 버전 기록을 열었다. 정상 완료 토큰은 버전 3.2, 취소 토큰은 버전 3.2의 중계 요청에서 파생된 3.2-R이었다. 둘은 같은 주문번호를 가졌지만, 발급 서비스는 달랐다. 정상 토큰은 배송 플랫폼, 취소 토큰은 외부 정리 서비스였다.

“외부 서비스가 배송 완료를 취소한 겁니다.” 민우가 말했다.

“취소한 것과 재발급한 것은 다릅니다.” 서진이 답했다. “이 토큰은 정상 완료를 지우지 않았습니다. 별도 기록을 추가했습니다.”

토큰의 결제 기록을 열자 외부 서비스 계정에는 작은 금액의 정리 수수료가 붙어 있었다. 결제자는 물류회사였고, 결제 승인 시각은 04:04:02였다. 사진 생성 45초 뒤였다. 그 시간차는 누군가 사진을 만들고 나서 기록을 정리했을 가능성을 높였지만, 자동 정산일 수도 있었다.

서진은 자동 정산 가설을 먼저 만들었다. 배송 오류가 발생하면 시스템이 자동으로 재발급하고 수수료를 붙이는 구조. 이 가설이 맞다면 사람의 개입 없이도 두 토큰이 생길 수 있었다. 플랫폼은 자동 규칙표를 제출해야 했다.

송주혁은 외부 서비스 계약의 해당 조항을 열람하지 않겠다고 했다. 대신 계약 권한의 해시와 수수료 승인 기록을 보호기관을 통해 넘겼다. 그는 회사가 자동 규칙을 언제 적용했는지 알고 있었지만, 다른 작업자의 계정이 함께 드러나는 원문은 공개하지 않았다.

“이 자료로는 자동인지 사람이 눌렀는지 구분할 수 없습니다.” 민우가 말했다.

“그래서 접근 흔적을 봅니다.” 서진은 답했다.

외부 검토자는 토큰 발급 서버의 접근 기록을 비교했다. 자동 규칙은 지정된 서버에서만 발급돼야 했지만, 04:03:18에 관리자용 접근 경로가 한 번 열렸다. 접근 주체는 계약 대행사 계정으로 가려져 있었고, 그 계정은 사건 한 달 전 새로 활성화됐다. 자동 규칙만으로는 설명되지 않는 접근이었다.

그러나 관리자용 접근이 토큰을 만들었다는 뜻은 아니었다. 시스템은 자동 규칙을 수동으로 재실행할 때도 같은 경로를 열 수 있었다. 사람의 개입 가능성과 자동 재실행 가능성이 동시에 남았다.

서진은 두 가설을 표로 나눴다. 첫째, 외부 서비스 직원이 배송 사진을 보고 수동으로 토큰을 재발급했다. 둘째, 자동 규칙이 실패해 관리자가 재실행했고, 사진과 토큰의 순서가 우연히 겹쳤다. 어느 가설도 약품 이동과 문세림의 사망을 직접 설명하지 못했다.

민우는 사건 내부 자료를 옆에 붙였다. 냉장 보관함의 전력, 상변화 라벨, 테스트폰 센서 결함. 약품이 창고에서 먼저 이동했고, 사진은 그 뒤 테스트폰으로 만들어졌으며, 토큰은 다시 외부 서비스에서 파생됐다. 물리 사건과 기록 정리가 병렬로 놓인 구조였다.

송주혁은 그 표의 외부 서비스 부분을 한참 읽었다. 그는 계약 대행사의 이름을 알고 있었지만, 바로 말하지 않았다.

“말하지 않으면 우리가 다음 보존 시한을 놓칠 수 있습니다.” 서진이 말했다.

“말하면 그 회사에서 일했던 사람들까지 조사받을 겁니다.”

“그 위험을 줄일 수 있는 범위를 먼저 정하죠.”

송주혁은 보호기관과 통화한 뒤, 계약 대행사의 회사명과 권한이 유효했던 날짜만 공개했다. 직원 이름과 개인 연락처는 제외했다. 외부 검토자는 그 정보로 계약 권한표와 접근 로그의 계정 종류를 비교했다.

나리는 수첩의 특정 페이지에 같은 회사명이 반복된다는 사실만 확인해 주었다. 그녀는 원문을 건네지 않았고, 서진은 복사본을 요구하지 않았다. 대신 나리의 확인서에는 페이지 번호와 확인 시각만 남았다. 외부 조직 연결은 강화됐지만, 하나의 조직이 모든 사건을 지휘한다는 결론은 아직 나오지 않았다.

여름은 사건 내부의 부분 해답을 먼저 당사자에게 전달하자고 했다. 문세림의 가족에게는 약품이 창고 안에서 전환된 가능성과 배송 기록이 사후 정리된 흔적을 설명하고, 외부 조직 연결은 확정되지 않은 가설로 남기는 방식이었다. 피해자에게 조직 이야기를 먼저 주면, 정작 사망의 직접 경로가 흐려질 수 있었다.

민우는 가족에게 설명할 자료를 만들었다. 냉장팩 라벨의 상변화, 보관함 전력, 테스트폰 사진 시각, 토큰 버전과 수수료. 네 가지는 확인된 사실로, 외부 서비스의 수동 개입은 검증 중인 가설로 구분했다.

서진은 그 설명 자리에 함께 들어갔다. 문세림의 동생은 사진을 보지 않고도 약품이 어디에서 움직였는지 알 수 있느냐고 물었다.

“현재 확인된 자료로는 창고 안 냉장 보관함에서 먼저 이동했을 가능성이 큽니다. 누가 옮겼는지는 아직 확정하지 않았습니다.”

“그럼 배송 완료 사진은 거짓말입니까?”

“사진이 찍혔다는 사실은 맞습니다. 사진이 실제 배송 순간을 뜻하는지는 확인 중입니다.”

동생은 고개를 숙였다. 서진은 이 설명이 가족에게 즉시 위로가 되지 않는다는 것을 알았다. 부분 해답은 완전한 결론보다 덜 시원했지만, 확인되지 않은 사람을 범인으로 만들지 않는 최소한의 정직이었다.

저녁에 플랫폼은 3.2-R 토큰의 승인 경로 일부를 추가로 공개했다. 정상 배송기기의 지역과 외부 서비스 관리자 계정의 지역이 사건 시각에 같았다. 하지만 지역은 물류창고 전체를 포함했고, 계정 사용자의 위치를 특정하지 않았다. 서진은 그 사실을 ‘같은 장소권역’이라고만 기록했다.

민우가 말했다. “이 정도면 외부 서비스가 내부 범행을 정리했다고 볼 수 있지 않습니까?”

“정리했을 가능성은 높아졌습니다. 누가 지시했는지는 아직입니다.”

송주혁은 그때 처음으로 부분 증거를 하나 더 내놓았다. 사건 전날 회사 내부에서 외부 정리 서비스에 보낸 계약 변경 요청의 해시였다. 문서 내용은 공개하지 않았지만, 변경 요청이 배송 오류 정리에서 수동 승인 검토로 바뀐 날짜는 확인됐다. 변경은 사건 두 주 전이었다.

“왜 지금 줍니까?” 민우가 물었다.

“이제는 사람 이름 없이도 계약 구조를 볼 수 있으니까요.”

서진은 그 자료를 외부 검토자에게 넘겼다. 계약 변경 시각과 관리자 계정 활성화 시각이 가까웠다. 외부 서비스가 사건 이전부터 수동 개입 권한을 준비했을 가능성이 생겼지만, 그것이 이번 사건을 위해서였다고 단정할 수는 없었다.

회색실 팀은 외부 조직 연결을 공개하지 않기로 했다. 대신 사건 내부 범행의 부분 해답과, 외부 정리 서비스의 권한 확대라는 장기 질문을 분리해 기록했다. 송주혁은 보호 대상의 신원을 독점하지 않고, 회사 계약의 일부만 넘겼다. 그가 가진 정보가 팀의 것이 되지 않았지만, 사건의 경계는 넓어졌다.

밤 열한 시, 누군가 외부 서비스의 관리자 권한표를 회수하려는 요청을 보냈다. 요청자는 물류회사 법무 계정이었고, 회수 대상에는 04:03 토큰의 보존 로그도 포함돼 있었다. 여름은 즉시 보존 상태를 갱신했고, 서진은 회수 요청의 발신 시각을 기록했다.

민우가 외투를 입었다. “이번에는 회사가 직접 자료를 가져가려는군요.”

“그렇다고 같은 조직이라고 쓰지는 마세요.”

그는 씁쓸하게 웃었다. “아직도 그 말을 하는군요.”

“그 말을 계속해야 다음 가설이 정확해집니다.”

서진은 사건표의 마지막에 적었다.

‘사건 내부에서 약품 전환과 기록 재발급의 연결이 확인되었다. 외부 정리 서비스의 관리자 권한과 결제·접근 흔적은 장기 조사로 승격한다. 지휘 구조는 미확정이며, 원문 공개 없이 반대 승인 로그와 계약 권한으로 입증한다.’

파란 삼각형 영수증의 고객번호와 3.2-R 토큰 버전이 같은 자료함에 들어갔다. 첫 사건의 도구가 두 번째 사건의 기록을 만지고 있었다. 하지만 서진은 아직 그 손의 이름을 쓰지 않았다. 다음 날 아침, 문세림의 가족은 회색실에 다시 왔다. 서진은 그들에게 외부 서비스의 이름을 먼저 말하지 않았다. 먼저 약품이 창고의 냉장 보관함에서 이동했을 가능성과, 배송 완료 사진이 그 이동 뒤에 만들어졌을 가능성을 설명했다.

동생은 사진을 보지 않고 질문했다. “그럼 누가 언니를 창고에 남겼는지는요?”

“그 부분은 아직 수사 중입니다. 송주혁 씨의 보호 대상과 사진·토큰을 만든 사람을 같은 사람으로 보지 않고 있습니다.”

“그 사람을 보호하는 게 언니보다 중요합니까?”

서진은 잠시 말을 고르다 답했다. “중요도의 문제가 아니라, 확인된 사실의 범위를 지키는 문제입니다. 확인되지 않은 이름을 공개하면 언니의 사건도 잘못된 방향으로 갈 수 있습니다.”

동생은 쉽게 납득하지 못했지만, 설명서를 받아 갔다. 그 문서에는 확인된 사실과 가설이 다른 색으로 표시돼 있었다. 가족이 나중에 공개 범위를 다시 묻거나 정정할 수 있는 날짜도 적혀 있었다.

송주혁은 그 설명을 듣고 자신의 계약 변경 해시를 추가로 보존했다. 그는 보호 대상의 이름을 말하지 않고, 회사 내부에서 외부 서비스 권한을 늘린 사람이 누구인지도 특정하지 않았다. 대신 승인권한의 변경 시각과 결재 단계만 넘겼다.

민우가 말했다. “부분 증거만 계속 주면, 우리가 나머지를 못 찾을 수 있습니다.”

“그러면 못 찾은 책임은 여러분이 지세요. 제가 사람 이름으로 빈칸을 채우게 하지는 않겠습니다.”

서진은 그 말을 회의록에 남겼다. 송주혁은 정보를 독점하지 않았지만, 공개 조건을 정함으로써 수사의 속도를 통제하고 있었다. 그 통제는 불편했지만, 당사자의 거부권이 실제로 작동한 결과였다.

외부 서비스의 관리자 권한 회수 요청은 법무 계정의 자동 절차로 확인됐다. 사람이 사건을 숨기려 한 것인지, 계약 종료에 따른 정리인지 아직 알 수 없었다. 여름은 회수 요청을 보존하고, 물류회사에 회수 사유와 승인자를 서면으로 묻기로 했다.

서진은 파란 삼각형의 고객번호와 3.2-R 버전의 결제 식별자를 나란히 놓았다. 동일 계열 가능성은 높아졌지만, 그 가능성을 확정하는 데 필요한 것은 반복되는 모양이 아니라 반대 승인 로그와 계약 권한이었다. 다음 단계는 원문을 폭로하는 것이 아니라, 누가 어떤 권한으로 기록을 바꿀 수 있었는지를 확인하는 일이었다.

이번 화가 재미있었나요?

좋아요와 평점은 언제든 변경할 수 있습니다.

독자 평점 아직 없음

댓글

댓글을 작성하려면 로그인해 주세요.