MOM.SOFT

MOMSOFT  /  기술 블로그

CTO · 조직

외주 개발 계약에서 반드시 정해 두어야 할 것들

분쟁이 나는 지점은 대체로 정해져 있습니다. 계약서에 여섯 문단만 제대로 넣어도 다툼의 절반은 협의로 바뀝니다.

프로젝트 문의하기 →

결론부터 적겠습니다. 외주 개발에서 생기는 분쟁의 대부분은 새로운 종류의 사고가 아닙니다. 요구사항 변경, 산출물과 인수 기준, 소스와 지식재산 귀속, 하자보수 범위, 인력 교체, 운영 이관 — 이 여섯 자리에서 반복해서 터집니다. 그리고 이 여섯 가지는 모두 계약 시점에 몇 문단으로 정할 수 있는 것들입니다. 정해 두지 않으면 나중에 "상식적으로는" "관행적으로는" 같은 말로 싸우게 되고, 그 싸움에는 이긴 쪽도 손해만 남습니다.

여기서 말하는 계약서는 법률 문서 한 벌을 새로 쓰자는 뜻이 아닙니다. 표준 도급계약서에 기술 부속합의서 몇 장을 붙이는 것으로 충분한 경우가 많습니다. 중요한 건 분량이 아니라, 다툼이 생길 지점을 미리 문장으로 확정해 두었는지입니다. 아래 내용은 실무에서 반복되는 판단 기준을 정리한 것이고, 조문의 최종 형태와 법적 효력은 사안에 따라 달라지므로 금액이 큰 계약이라면 법률 자문을 별도로 받으십시오.

발주자 입장에서만 쓰지 않겠습니다. 수급자(개발사) 쪽에서 반드시 지켜야 할 방어선도 같이 적습니다. 한쪽만 유리한 계약은 결국 품질로 대가를 치릅니다.

왜 같은 자리에서만 터지는가

소프트웨어 도급계약의 구조적 문제는 하나입니다. 계약 시점에 만들 물건이 확정되어 있지 않다는 것. 건축은 도면이 먼저 나오고 시공이 뒤따르지만, 소프트웨어는 도면을 그리는 행위 자체가 개발 과정의 상당 부분입니다. 그래서 계약서에는 "요구사항정의서에 따른다"고 쓰여 있는데, 정작 그 요구사항정의서는 계약 후에 작성됩니다.

여기서 두 가지 비대칭이 생깁니다.

계약서의 역할은 이 비대칭을 없애는 게 아니라, 비대칭이 커지기 전에 판단 절차를 고정해 두는 것입니다. "누가, 언제, 어떤 근거로 결정하는가"만 정해도 대부분의 감정 싸움은 사무적 협의로 내려앉습니다.

먼저 계약 형태를 고르십시오

여섯 항목을 적기 전에 결정할 것이 하나 있습니다. 이 일을 결과물을 사는 계약(고정가 도급)으로 할지, 시간을 사는 계약(투입 공수형)으로 할지입니다. 이 선택이 아래 여섯 항목의 무게를 전부 바꿉니다.

구분고정가 도급투입 공수형
적합한 상황범위를 문서로 굳힐 수 있을 때범위가 진행하며 드러날 때
변경 절차무겁게 — CR이 곧 금액가볍게 — 우선순위 조정으로 흡수
인수 기준테스트 케이스로 촘촘히스프린트 단위 확인 + 최종 범위 합의
리스크 부담개발사(견적에 버퍼가 붙음)발주자(관리 책임이 따라옴)

범위가 흐린 일을 고정가로 묶으면 개발사는 버퍼를 얹고, 그 버퍼를 발주자가 눈치채면 다시 깎으라고 하고, 깎인 만큼 나중에 CR로 되돌아옵니다. 반대로 범위가 명확한 일을 투입 공수형으로 하면 발주자가 관리 비용을 전부 떠안습니다. 흔한 절충은 설계 단계만 투입 공수형으로 짧게 끊고, 그 산출물을 기준선 삼아 구축 단계를 고정가로 다시 계약하는 2단계 구조입니다.

1. 요구사항 변경 처리 절차

가장 많이 터지고, 가장 쉽게 막을 수 있는 지점입니다. 핵심은 "변경을 막는다"가 아니라 "변경에 값을 매기는 절차를 만든다"입니다. 변경을 금지하면 발주자는 회의 자리에서 구두로 밀어 넣고, 개발사는 거절하지 못한 채 일정만 밀립니다.

정해 두어야 할 것

[변경요청서 최소 항목]
요청일 / 요청자 / 대상 기능
변경 전 <-> 변경 후 (기준선 문서의 어느 항목인지 명시)
영향: 공수, 일정, 비용, 다른 기능에 대한 파급
승인자 서명 / 반려 사유

절차가 있어도 무너지는 전형적인 경로가 하나 있습니다. 개발사가 "이 정도는 그냥 해 드리겠습니다"를 반복하는 경우입니다. 무상 처리 자체가 문제는 아니지만, 무상으로 하더라도 CR은 발행해서 기록을 남기십시오. 무상 처리분이 누적된 기록이 있어야 나중에 "왜 일정이 밀렸는가"를 설명할 수 있습니다. 기록 없는 호의는 분쟁 시점에 존재하지 않았던 일이 됩니다.

수급자 쪽 방어선 하나. "협의 후 반영"이라는 표현을 계약서에 남기지 마십시오. 이 단어는 분쟁이 되면 "협의만 하면 반영해야 한다"로 읽히기 쉽습니다. "협의하여 별도 합의한 범위에서 반영한다"로 바꾸는 것만으로 의미가 달라집니다. 같은 이유로 "발주자가 요구하는 수준으로", "업계 통상 수준으로" 같은 열린 표현도 지우십시오. 판단 주체가 한쪽에만 있는 문장은 조항이 아니라 백지수표입니다.

2. 산출물 정의와 인수 기준

"프로그램 일체"라고만 쓰인 계약서를 자주 봅니다. 그러면 검수 단계에서 "빌드가 안 되는데요" "그건 저희 개발 환경에서만 되던 겁니다" 같은 대화가 오갑니다. 산출물은 목록으로 적어야 합니다.

산출물 목록에 반드시 들어가야 하는 것

목록보다 강한 조항이 하나 있습니다. "클린 체크아웃 재현"입니다. 빈 장비에 저장소를 새로 내려받아 문서에 적힌 절차만으로 빌드와 기동이 되는지 검수 항목에 넣으십시오. 이 한 줄이 "개발자 노트북에만 있는 설정"을 전부 밖으로 끄집어냅니다. 인프라 구성이 코드로 관리되고 있다면 이 검증은 몇십 분이면 끝나고, 아니라면 그 사실 자체가 이관 리스크의 크기를 알려 줍니다.

인수 기준은 측정 가능해야 한다

"정상 동작할 것"은 기준이 아닙니다. 인수 기준은 사전에 합의된 테스트 케이스로 표현되어야 하고, 성능 조건을 넣는다면 반드시 측정 조건이 함께 있어야 합니다.

나쁜 기준: "조회 속도가 빨라야 한다"
쓸 만한 기준: "동시 사용자 N명, 데이터 M건 기준
              목록 조회 응답이 T초 이내.
              측정 도구/환경/회차/백분위는 부속서에 정의."

여기서 N, M, T는 반드시 양측이 실제로 합의한 값이어야 합니다. 남의 프로젝트 숫자를 옮겨 적으면 그 숫자가 나중에 발목을 잡습니다. 하나 더. 성능 수치를 쓸 때는 평균인지 백분위인지를 반드시 적으십시오. 평균만 적힌 조항은 사용자가 체감하는 느린 요청을 전부 통과시킵니다. 그리고 측정 환경이 운영 환경과 다르다면(대개 다릅니다) 그 차이를 조항에 명시해야 합니다. 스펙이 낮은 검수 서버에서 잰 값으로 운영 성능을 보증하라는 요구는 개발사가 받으면 안 되는 조건입니다.

검수 절차의 시간 조항

항목정해 둘 내용빠뜨리면 생기는 일
검수 기간산출물 제출일로부터 며칠검수가 무한정 늘어져 대금이 묶임
무응답 처리기간 내 의견이 없으면 인수된 것으로 본다발주자가 침묵으로 잔금을 지연
재검수보완 후 재검수 기간과 횟수 상한사소한 지적으로 검수 무한 반복
부분 인수모듈 단위 인수와 대금 연동 여부한 기능 때문에 전체 대금 정지
결함 등급등급 정의와 인수를 막는 등급의 경계사소한 결함이 인수 거부 사유가 됨
지체상금요율과 상한, 귀책 제외 사유지연 하나로 계약금액을 넘는 배상 청구

표에서 실무상 가장 자주 빠지는 줄은 결함 등급입니다. 등급 정의가 없으면 "오탈자 세 건"과 "결제가 안 됨"이 같은 무게의 반려 사유가 됩니다. 등급을 세 단계로만 나누고, 인수를 막는 등급과 인수 후 하자보수로 넘기는 등급의 경계를 한 문장으로 적어 두면 검수 회의의 절반이 사라집니다.

무응답 자동인수 조항은 발주자가 본능적으로 싫어합니다. 하지만 이 조항이 없으면 개발사는 잔금을 인질로 잡힌 상태로 무상 개발을 계속하게 되고, 그 손실은 결국 품질과 다음 요청의 거절로 돌아옵니다. 기간을 넉넉히 잡되 조항 자체는 남기는 편이 양쪽에 낫습니다. 발주자 쪽에서 이 조항이 불안하다면, 자동인수 기간의 기산점을 "산출물 제출일"이 아니라 "검수 환경에서 인수 테스트가 가능해진 날"로 잡으면 대부분의 우려가 해소됩니다.

3. 소스와 지식재산의 귀속

"소스는 당연히 우리 것 아닌가요"라는 질문이 가장 자주 나오는 대목입니다. 당연하지 않습니다. 아무 말이 없으면 저작권은 원칙적으로 실제로 창작한 쪽에 남습니다. 계약서에 양도 문구가 있어야 넘어옵니다.

세 층으로 나누어 적으십시오

  1. 본 계약으로 새로 만든 결과물 — 발주자에게 저작재산권을 양도할지, 이용허락(라이선스)만 줄지. 양도라면 어느 시점에 이전되는지(보통 잔금 완납 시점).
  2. 개발사가 이전부터 보유한 공통 자산 — 사내 프레임워크, 공통 모듈, 유틸리티 라이브러리. 이건 넘기지 않는 대신 발주자에게 영구·비독점 사용권을 주는 방식이 일반적입니다. 이 층을 명시하지 않고 "일체 양도"에 서명하면, 개발사는 자기 회사의 축적 자산을 잃고 발주자는 대신 단가를 더 냅니다. 양쪽 다 손해입니다.
  3. 제3자 자산 — 오픈소스와 상용 라이브러리. 목록과 라이선스를 산출물에 포함시키고, 카피레프트 계열 라이선스가 포함되는 경우 사전 고지 의무를 넣으십시오. 배포 형태에 따라 소스 공개 의무가 발생할 수 있는 컴포넌트가 제품 핵심에 들어가 있는 걸 이관 후에 발견하면 손쓸 방법이 마땅치 않습니다. 상용 라이브러리는 라이선스 명의가 개발사인지 발주자인지, 이관 시 승계가 되는지까지 확인해야 합니다.

2차적저작물 작성권 — 흔히 반대로 알고 있는 조항

여기서 자주 인용되는 규정이 저작권법의 저작재산권 양도 조항(제45조 제2항)입니다. 저작재산권 전부를 양도해도 특약이 없으면 2차적저작물을 작성하여 이용할 권리는 포함되지 않은 것으로 추정한다는 내용입니다. 그런데 이 조항에는 단서가 붙어 있고, 프로그램의 경우에는 추정이 반대로 뒤집혀 특약이 없는 한 2차적저작물작성권도 함께 양도된 것으로 추정합니다. 즉 "소스 코드를 넘겨받았는데 고쳐 쓸 권리가 없다"는 식의 흔한 설명은 프로그램에 대해서는 그대로 적용되지 않습니다.

그렇다고 이 문장을 빼도 된다는 뜻은 아닙니다. 명시해야 하는 이유가 세 가지 있습니다.

그래서 실무적으로는 "본 결과물에 관한 저작재산권 일체를 2차적저작물 작성권을 포함하여 양도한다"는 한 줄을 넣고, 프로그램이 아닌 산출물까지 포괄되도록 대상 범위를 함께 적는 것이 안전합니다.

그 외 흔히 빠뜨리는 조항

4. 하자보수의 범위와 기간

하자보수 분쟁의 본질은 기간이 아니라 정의입니다. 개발사는 "그건 개선 요청"이라 하고 발주자는 "그건 하자"라고 합니다. 판단 기준을 계약서에 박아 두십시오. 기준은 하나면 충분합니다.

인수 기준(합의된 요구사항·테스트 케이스)에 미달하면 하자, 인수 기준에는 부합하나 다르게 동작하기를 원하면 변경이다.

상황분류
명세대로 만들었으나 오류로 값이 틀림하자 — 무상 보수
명세에 없던 예외 케이스를 추가로 처리해 달라변경 — CR 절차
외부 연동 기관의 규격이 바뀌어 동작 불가변경 또는 유지보수 — 원칙적으로 하자 아님
OS·브라우저·런타임 상위 버전에서 동작 이상지원 대상 버전을 계약서에 적었는지에 따라 갈림
사용 중인 라이브러리에서 보안 취약점이 공개됨하자 아님 — 보안 패치 대응은 유지보수 범위로 별도 합의
발주자가 임의로 소스를 수정한 뒤 발생한 오류하자 아님 — 면책 조항 필요
데이터 급증으로 성능 저하인수 기준의 데이터 규모 조건을 넘었는지로 판단

같이 정할 것

5. 인력 교체와 인수인계

제안서에 실린 시니어가 착수 후 조용히 사라지는 일은 드물지 않습니다. 반대로 발주자가 특정 개발자를 사실상 파견 인력처럼 붙잡아 두려는 경우도 있습니다. 둘 다 계약으로 다뤄야 합니다.

수급자 쪽 방어선. 상주·근태 관리 조항은 조심해야 합니다. 도급으로 계약하고 실질은 발주자로부터 직접 지휘·명령을 받는 형태로 운영되면 계약의 성격 자체가 다르게 평가될 수 있습니다. 업무 지시 경로를 개발사 PM으로 단일화한다는 문장을 넣어 두고, 실제 운영도 그렇게 하십시오. 문장만 있고 현장에서 발주자 담당자가 개별 개발자에게 직접 지시하고 있으면 그 문장은 도움이 되지 않습니다.

발주자 쪽에도 대칭적인 방어선이 있습니다. 인력 이탈을 지연 사유로 인정하지 않는다는 문장입니다. 그리고 착수 시점에 이름과 함께 투입률(전담인지 겸업인지)을 적어 두십시오. 실무에서 더 흔한 문제는 사람이 빠지는 것이 아니라, 이름은 그대로인데 다른 프로젝트와 나눠 쓰면서 실제 투입 시간이 줄어드는 경우입니다.

6. 운영 이관 조건

가장 늦게 논의되고, 가장 크게 터지는 항목입니다. 개발이 끝나도 서비스는 계속 돌아야 하는데, 돌리는 데 필요한 것들이 개발사 손에만 있는 상태가 흔합니다. 이관은 파일 전달이 아니라 능력의 이전입니다.

이관 대상 목록

모바일 앱은 이 목록에서 따로 떼어 볼 필요가 있습니다. 안드로이드는 서명 키를 누가 쥐고 있는지가 핵심입니다. 스토어의 앱 서명 서비스에 등록해 두었다면 업로드 키를 잃어버려도 재발급 절차가 있지만, 앱 서명 키를 개발사가 직접 관리하는 방식이라면 그 키를 잃는 순간 같은 패키지명으로 업데이트를 올릴 수 없습니다. 어느 방식으로 운영되고 있는지를 계약 단계에서 확인하고 산출물 목록에 적으십시오. iOS는 계정 명의 문제가 더 큽니다. 개발자 계정이 개발사 명의로 되어 있으면 나중에 앱을 넘기는 절차가 따로 필요하고 조건도 붙으므로, 처음부터 발주자 명의 계정을 만들고 개발사를 구성원으로 초대하는 편이 훨씬 간단합니다. 인증서와 프로비저닝 프로파일은 발급 주체가 아니라 계정 소유권이 실질을 결정합니다.

이관을 '완료'로 인정하는 조건

목록만으로는 부족합니다. 완료 판정 기준을 하나 넣으십시오. 가장 확실한 것은 이것입니다.

인수자 측 인력이 개발사의 도움 없이 스테이징 환경에 배포하고, 롤백까지 수행하는 것을 양측 입회하에 성공하면 이관을 완료로 본다.

여기에 병행 운영(안정화) 기간, 그 기간의 대응 범위와 대가, 이관 이후 개발사가 보유한 발주자 데이터의 파기 및 확인서 제출까지 붙이면 대체로 충분합니다. 개인정보가 포함된 시스템이라면 개발·운영 과정에서 개발사가 개인정보를 다루는지, 다룬다면 처리 위탁 관계로 문서화되어 있는지와 재위탁 동의 절차를 계약과 함께 정리해야 합니다. 여기서는 계약서보다 실제 운영이 문제가 됩니다. 운영 데이터를 개발 환경으로 복사해 쓰고 있다면 그 관행부터 정리하는 것이 조항보다 먼저입니다.

마지막으로 유지보수 계약은 개발 계약과 분리하되, 계약 시점에 이후 유지보수 단가의 산정 방식이나 상한을 미리 합의해 두십시오. 이관 직전은 발주자의 협상력이 가장 낮은 시점입니다. 개발사 쪽에서도 이 합의는 손해가 아닙니다. 유지보수 조건을 미리 정해 두면 프로젝트 후반의 무리한 무상 요구를 "그건 유지보수 범위입니다"라는 한 문장으로 정리할 수 있습니다.

착수 전 체크리스트

계약서에 다음 항목이 각각 한 문단 이상으로 존재하는지만 확인하면 됩니다. 문장이 없다면 그 자리에서 분쟁이 납니다.

  1. 계약 형태(고정가 · 투입 공수 · 단계 분리)와 그 선택의 근거
  2. 기준선이 되는 문서와 그 확정 시점 · 확정 방법
  3. 변경요청 경로, 영향 평가 회신 기한, 승인 권한자 이름, 경미 변경 쿼터
  4. 산출물 목록 (소스 · 빌드 · 인프라 · 문서 · 테스트 · 라이선스 목록)과 클린 체크아웃 재현 검증
  5. 인수 테스트 케이스, 성능 기준의 측정 조건, 결함 등급, 검수 기간과 무응답 처리, 재검수 상한
  6. 대금 지급 마일스톤과 인수의 연결, 지체상금 요율과 상한
  7. 저작재산권 양도 범위 · 이전 시점 · 2차적저작물 작성권 · 프로그램이 아닌 산출물의 처리 · 개발사 보유 자산의 사용권 · 오픈소스 목록 제출
  8. 하자와 변경의 구분 기준, 하자보수 기간의 기산점, 지원 대상 환경, 등급별 대응 목표
  9. 핵심 인력 지정과 투입률, 교체 절차와 중복 근무, 재하도급 통지 의무
  10. 이관 대상 자산 목록(서명 키 · 계정 명의 포함)과 이관 완료 판정 기준, 병행 운영 기간
  11. 비밀유지 기간, 개인정보 처리 위탁 관계와 재위탁, 손해배상 한도

손해배상 한도는 마지막에 적었지만 실제로는 매우 중요합니다. 상한 없는 배상 조항에 서명한 소규모 개발사는 사고 한 번으로 사업이 끝날 수 있습니다. 계약금액을 기준으로 한 상한과, 간접손해·일실이익 제외 문구를 확인하십시오. 다만 고의·중과실, 비밀유지 위반, 지식재산권 침해는 상한에서 제외하는 것이 일반적이고, 그 예외를 통째로 없애 달라는 요구는 발주자가 받아들이기 어렵습니다. 협상의 실질은 "상한을 없앨 것인가"가 아니라 "상한의 배수와 예외 항목을 어디까지로 볼 것인가"입니다.

언제는 이렇게 하지 말아야 하는가

지금까지의 내용을 모든 계약에 그대로 적용하면 오히려 일이 안 됩니다. 다음 경우에는 의도적으로 덜어내야 합니다.

규모가 아주 작을 때

랜딩 페이지 하나, 화면 몇 개짜리 내부 도구에 위 항목을 다 붙이면 계약 협의 비용이 개발비를 넘습니다. 이 경우엔 세 가지만 남기십시오. 산출물 목록, 소스 귀속, 대금 조건. 나머지는 분쟁이 나도 손실이 계약금액을 넘지 않습니다. 판단 기준은 단순합니다. 최악의 손실이 계약금액 안에서 끝나는가. 그렇다면 계약서를 두껍게 만드는 것은 낭비입니다.

결과물이 아니라 탐색이 목적일 때

기술 검증(PoC), 타당성 조사, 프로토타입은 고정가 · 확정 산출물 계약으로 묶으면 안 됩니다. 무엇을 만들지 모르는 상태에서 인수 기준을 정하면, 그 기준을 채우려고 검증이 아닌 시연용 코드를 만들게 됩니다. 이런 일은 기간과 투입 공수를 사고, 산출물은 "보고서와 실험 코드"로 정의하는 편이 정직합니다. 그리고 그 코드를 그대로 운영에 올리지 않는다는 문장을 같이 넣으십시오. PoC 코드가 운영 시스템의 뼈대가 되는 사고는 계약이 아니라 이 한 줄로 막습니다.

상대가 1인 개발자나 소규모 팀일 때

대기업 표준계약서를 그대로 들이대지 마십시오. 무한 손해배상, 전부 양도, 장기 무상 하자보수, 과도한 지체상금을 요구하면 두 가지 중 하나가 일어납니다. 역량 있는 팀은 견적을 올리거나 그냥 거절하고, 남는 건 조항을 제대로 읽지 않은 팀입니다. 계약 조건이 가혹하면 지원자 풀의 품질이 먼저 떨어집니다. 조항으로 회수할 수 없는 리스크는 조항을 강화해서 줄이는 게 아니라, 검수 주기를 짧게 가져가서 줄이는 것이 맞습니다.

공통 프레임워크까지 양도를 요구할 때

발주자가 "일체 양도"를 고집하면 개발사는 두 가지로 대응합니다. 자기 자산을 쓰지 않고 처음부터 짜거나(비용·기간 증가, 품질 저하), 자산을 넣고 침묵하거나(나중에 더 큰 분쟁). 프로젝트 고유 결과물과 개발사 공통 자산을 나누고, 후자는 사용권으로 받는 것이 실질적으로 발주자에게도 이익입니다. 발주자가 정말로 확보해야 하는 것은 소유권이 아니라 다른 업체로 갈아탈 수 있는 상태이고, 그건 영구 사용권과 온전한 이관 산출물로 충분히 확보됩니다.

절차를 신뢰의 대체물로 쓸 때

가장 중요한 항목입니다. 계약서는 사이가 나빠졌을 때 참조하는 문서이지, 사이를 좋게 만드는 도구가 아닙니다. 매주 회의에서 진행 상황을 같이 보고, 동작하는 걸 자주 확인하고, 나쁜 소식을 일찍 말할 수 있는 관계가 되어 있으면 위 조항의 대부분은 한 번도 펼치지 않습니다. 반대로 관계가 무너진 뒤에는 아무리 잘 쓴 계약서도 손실을 줄여 줄 뿐 프로젝트를 살리지는 못합니다.

그러니 순서는 이렇습니다. 계약서로 최악의 경우의 손실 크기를 확정하고, 그다음 일상적인 협업으로 최악이 올 확률을 낮춥니다. 둘 중 하나만 하는 조직이 대부분이고, 사고는 늘 빠진 쪽에서 납니다.

같은 주제의 다른 글

맘소프트는 19년 넘게 금융 · 엔터프라이즈 · 모바일 시스템을 만들어 왔습니다. 여기 적는 글은 그 과정에서 실제로 부딪히고 해결한 것들입니다.

기술 판단이 필요하신가요

맘소프트는 소프트웨어 개발과 CTO 대행 · 기술 자문을 제공합니다. 편하게 문의해 주세요.

[email protected]