오픈소스는 대부분의 제품에서 라이브러리 목록이 아니라 실행 경로입니다. 인증 토큰을 검증하고, 컨테이너 이미지를 만들고, 데이터베이스에 연결하고, telemetry를 내보내는 코드가 외부 프로젝트에서 옵니다. 이때 “취약점 스캔이 녹색인가”만으로는 충분하지 않습니다. 심각한 결함이 발견됐을 때 누가 패치를 내는지, 우리 팀이 얼마나 빨리 올릴 수 있는지, upstream이 멈추면 어떤 비용으로 갈아탈 수 있는지가 실제 복구 시간을 좌우합니다.
그래서 요즘 개발 조직에서 유지보수 지속가능성은 기부 배너를 눌러야 한다는 도덕 논의보다 공급망 SLO와 dependency portfolio 관리에 가까운 주제가 되고 있습니다. Dependency Budget이 새 import의 장기 비용을 묻는다면, Publish-time 공급망 검토는 배포 직전의 신뢰 경계를 다룹니다. 여기에 패키지 릴리스 격리 gate, CI/CD 보안과 공급망의 원칙을 붙여 “유지보수 가능한가”를 운영 가능한 질문으로 바꿔 보겠습니다.
이 글에서 얻는 것
- CVE 수와 유지보수 지속가능성 지표가 각각 무엇을 말하는지 구분합니다.
- 서비스 영향도에 따라 Tier 1 의존성을 좁히고 update·rollback 목표를 만듭니다.
- 후원, 상용 지원, 내부 기여, 대체 구현 중 무엇에 투자할지 판단하는 기준을 세웁니다.
- maintainer 활동을 사람 평가가 아닌 제품 회복력 지표로 다루는 주의점을 익힙니다.
핵심 개념/이슈
1) 인기와 유지보수 가능성은 같은 말이 아니다
다운로드 수, 별 수, 최근 커밋은 후보를 고르는 데 유용하지만 독립적으로는 약한 신호입니다. 오래된 안정 라이브러리는 커밋이 적어도 잘 운영될 수 있고, 반대로 활발한 저장소라도 단일 maintainer가 release·보안 대응·issue triage를 모두 떠안고 있을 수 있습니다. 그러므로 특정 maintainer의 개인 사정이나 온라인 활동을 추측해 등급을 매기면 안 됩니다. 팀이 확인해야 할 것은 공개적으로 검증 가능한 릴리스 경로와 대응 능력입니다.
예를 들어 다음 질문은 사생활을 침해하지 않으면서 운영 위험을 드러냅니다. 최근 보안 수정이 release artifact까지 도달한 기록이 있는가? 지원되는 버전 범위가 문서화됐는가? 권한 있는 복수의 release manager 또는 명확한 승계 경로가 있는가? issue tracker와 보안 신고 창구가 분리돼 있는가? 패치가 나와도 우리 런타임·라이선스·호환성 제약 때문에 적용하지 못하는가? 마지막 질문은 upstream보다 우리 조직의 책임일 때가 많습니다.
| 신호 | 알려 주는 것 | 단독 사용 시 놓치는 것 |
|---|---|---|
| CVE·advisory | 알려진 취약점과 영향 범위 | 패치 적용 능력·실행 도달성 |
| release cadence | 변경이 배포되는 경로 | 안정 프로젝트의 의도적 저빈도 |
| bus factor 추정 | 운영 지식 집중 가능성 | 실제 권한 분산·승계 문서 |
| support window | 어떤 버전이 수정 대상인지 | 우리 서비스의 upgrade 난이도 |
| exit path | 대체·fork·제거 가능성 | 전환에 필요한 테스트·데이터 비용 |
2) Tier 1을 좁혀야 운영 가능한 약속이 된다
모든 transitive dependency를 같은 강도로 심사하면 아무 것도 제때 업데이트하지 못합니다. 먼저 인터넷 노출, 인증·암호, 결제, 빌드·배포, 데이터 직렬화, 운영 agent처럼 장애나 침해가 제품 전체로 퍼질 수 있는 경로만 Tier 1으로 분류하세요. 일반적인 서비스라면 처음에는 20~40개 이하의 직접·핵심 전이 의존성으로 시작하는 편이 현실적입니다. 전체 SBOM은 계속 유지하되, 사람이 보는 지속가능성 검토는 영향도가 큰 목록에 집중합니다.
Tier 1마다 owner, 현재 지원 버전, 패치 적용 목표, rollback 방식, 대체 후보를 한 줄로 기록합니다. 예를 들어 원격 코드 실행이나 인증 우회 등 high severity fix는 72시간 안에 영향·적용 가능성을 판정하고, 인터넷 노출 경로라면 7일 안에 완화 또는 업데이트를 목표로 둘 수 있습니다. 단순 lint plugin과 핵심 TLS 라이브러리에 같은 시간을 적용하면 우선순위가 무너집니다. “패치 없음”도 결론이 될 수 있지만, 왜 지금 취약하지 않은지와 다음 재확인 날짜를 남겨야 합니다.
3) 돈·시간·기여는 서로 대체되지 않는다
후원은 maintainership의 시간을 직접 늘릴 수 있지만, 우리 서비스의 upgrade friction을 자동으로 없애지는 않습니다. 상용 지원 계약은 사고 시 연락 경로와 SLA를 얻는 대신 vendor lock-in과 비용을 늘릴 수 있습니다. 내부 기여는 가장 필요한 개선을 앞당길 수 있지만 reviewer 시간과 장기 유지 책임을 동반합니다. fork는 최후의 안전망이지 “문제를 해결했다”는 상태가 아닙니다. 보안 patch와 ecosystem 호환성을 계속 따라갈 역량이 없다면 fork는 위험을 외부에서 내부로 옮길 뿐입니다.
의사결정의 순서는 보통 불필요한 의존성 제거 → 지원되는 버전으로 업그레이드 가능한 구조 확보 → upstream과의 공개적 협력 또는 지원 경로 확보 → 필요한 경우 재정·인력 기여 → 검증된 exit path가 낫습니다. 새 라이브러리를 넣을 때 이 순서를 뒤집어 “나중에 fork하면 된다”고 생각하면 테스트·문서·release 비용을 과소평가하게 됩니다.
실무 적용
1) 분기별 dependency resilience review를 30분으로 제한한다
거대한 감사 문서부터 만들 필요는 없습니다. 분기마다 Tier 1 목록을 30분 정도 검토하며 다음 네 가지 변화만 찾으세요. 지원 종료가 다가오는 버전, security fix를 막는 호환성 문제, release 권한 또는 대응 경로의 변화, 대체하기 어려운 사용 면적입니다. 새 evidence가 없으면 기존 결론을 복사하고 다음 검토일만 갱신합니다. 보고 자체를 목표로 하면 업데이트 PR이 지연됩니다.
| 등급 | 조건 | 기본 조치 |
|---|---|---|
| A | 지원 버전, 재현 가능한 release, owner와 rollback이 명확함 | 정기 업데이트·연 1회 exit test |
| B | 유지보수 신호는 있으나 upgrade 또는 대체 비용이 큼 | owner 지정·분기 검토·compatibility test 보강 |
| C | 지원 종료, security 대응 불명확, 단일 경로 의존 | 신규 사용 중지·90일 내 제거/지원/대체 결정 |
| D | 알려진 high-risk 결함과 대체 불가 상태가 겹침 | 완화·격리·executive risk acceptance를 즉시 결정 |
등급은 프로젝트의 평판표가 아니라 우리 시스템의 노출과 복구 가능성에 대한 판정입니다. 같은 라이브러리도 internal tool과 결제 API에서 등급이 달라질 수 있습니다. 외부 프로젝트에 “C”라는 라벨을 공개적으로 붙여 압박할 이유는 없고, 내부에서 필요한 조치를 정하는 데만 사용하세요.
2) update SLO를 운영 지표와 연결한다
SLO는 “CVE를 몇 개 닫았나”보다 알림 수신 → 영향 확인 → 완화 또는 배포 → 증거 기록의 시간을 재는 편이 낫습니다. High-risk advisory의 90%를 72시간 안에 영향 판정하고, 실제 노출된 Tier 1 경로의 90%를 7일 안에 완화 또는 fixed version으로 전환한다는 식으로 시작할 수 있습니다. 이 목표를 못 지키는 이유가 test 시간이 4시간인지, runtime upgrade가 불가능한지, package lockfile을 아무도 소유하지 않는지 분류해야 개선 지점이 보입니다.
변경 PR에는 최소한 이전·새 버전, lockfile diff, 영향 모듈, 테스트 명령, rollback 기준을 남기세요. 재현 가능한 build와 artifact provenance가 없으면 빨리 올렸다는 기록도 신뢰하기 어렵습니다. 자동 업데이트 봇은 PR을 열어 주지만, 지원 종료 경로와 제품 영향까지 판단하지는 못합니다.
트레이드오프/주의점
지속가능성 점수를 도입하면 팀이 “활동이 많은 프로젝트”만 고르려는 유혹을 받을 수 있습니다. 이는 안정적인 작은 프로젝트나 지역 커뮤니티를 부당하게 배제할 수 있습니다. 공개 활동량 대신 지원 버전, release 재현성, 보안 연락 경로, 우리 코드의 결합도처럼 검증 가능한 운영 사실을 우선하세요. 어떤 프로젝트에도 개인의 응답 속도나 사적 정보를 요구해서는 안 됩니다.
또한 모든 Tier 1에 후원이나 상용 계약이 답은 아닙니다. 먼저 사용 면적을 줄이고, wrapper를 통해 API 결합을 낮추며, upgrade test와 rollback을 자동화하는 것이 더 큰 위험 감소를 만들 수 있습니다. 후원은 중요한 생태계 기여가 될 수 있지만, 이를 구매 계약처럼 취급하거나 특정 결과를 기대하지 않는 원칙도 필요합니다.
체크리스트 또는 연습
- 인터넷 노출·인증·빌드·데이터 경로에 있는 Tier 1 의존성을 20~40개 이하로 먼저 좁혔다.
- 각 항목에 owner, 지원 버전, high-risk advisory의 영향 판정 목표, rollback 또는 exit path를 기록했다.
- 신규 의존성 PR에서 license·provenance·compatibility뿐 아니라 장기 유지·대체 비용을 확인한다.
- 분기 review는 최근 변화와 다음 조치만 30분 안에 확인하며, 개인 활동을 평가하지 않는다.
- high-risk advisory drill에서 영향 판정과 완화 증거를 72시간 목표로 남긴다.
연습으로 현재 서비스의 인증, 빌드, 데이터 직렬화 경로에서 라이브러리 하나씩만 골라 보세요. 각 항목에 “패치가 오늘 나왔을 때 누가, 어떤 테스트를 거쳐, 언제까지 올리는가”를 다섯 줄로 적습니다. 그 답이 라이브러리 이름이 아니라 owner·테스트·rollback·지원 경로까지 이어진다면, 오픈소스 지속가능성은 막연한 걱정이 아니라 관리 가능한 운영 항목이 됩니다.
💬 댓글