git 'detected dubious ownership' 에러 상황별 5분 해결 가이드
어제까지 잘 되던 git이 왜 갑자기 막혔을까
분명 어제까지 멀쩡하던 빌드인데, 오늘 갑자기 git status 한 줄에 빨간 에러가 뜹니다.
fatal: detected dubious ownership in repository at '/workspace'
To add an exception for this directory, call:
git config --global --add safe.directory /workspaceDocker 이미지를 새로 빌드했거나, CI 러너를 업그레이드했거나, 공유서버에 git 최신 버전이 깔린 직후라면 십중팔구 이 메시지를 만나게 됩니다. 먼저 안심하셔도 됩니다. 이건 코드 문제도, 리포지토리 손상도 아닙니다. 단순히 "디렉터리 소유자"와 "지금 명령을 실행하는 사용자"가 달라서 git이 안전을 위해 멈춰 선 것뿐입니다.
이 에러는 Git 2.35.2 / 2.30.3 등에 백포트된 보안 패치(CVE-2022-24765) 이후 폭증했습니다. 컨테이너 기반 CI/CD가 보편화되고, GitHub Actions self-hosted·컨테이너 job이 늘고, WSL2·NFS 공유 워크스페이스·모노레포가 일상이 되면서 "UID 불일치"가 평범한 풍경이 됐기 때문이죠. 급한 분은 아래 상황별 5분 해결책부터 복붙하고, 이유는 그다음에 읽으셔도 됩니다.
왜 이 에러가 생기는가: 소유자 ≠ 실행 사용자
git은 리포지토리 디렉터리의 소유자(owner UID) 와 지금 명령을 실행하는 현재 사용자의 UID 를 비교합니다. 둘이 다르면 git은 "혹시 다른 누군가가 이 디렉터리에 악성 .git/config(예: core.fsmonitor로 임의 명령 실행)를 심어둔 게 아닐까?"라고 의심하고 작업을 거부합니다. CVE-2022-24765의 핵심이 바로 이것입니다. /tmp처럼 누구나 쓸 수 있는 공유 경로에서, 공격자가 미리 만들어 둔 git 설정이 피해자의 권한으로 실행되는 시나리오를 막기 위한 의도된 방어죠. 즉 버그가 아니라 기능이며, 우리가 할 일은 "이 디렉터리는 내가 믿는 곳"이라고 git에게 명시적으로 알려주거나, 애초에 소유자를 실행 사용자와 일치시키는 것입니다.
상황별 5분 해결책 (복붙 명령 모음)
① 로컬 / 일반 환경
가장 흔한 케이스. 특정 경로 하나만 신뢰 목록에 추가합니다. <path>는 반드시 실제 절대경로로 바꿔주세요.
# <path>를 실제 리포지토리 절대경로로 교체 (예: /home/dev/myrepo)
git config --global --add safe.directory <path>이 명령은 ~/.gitconfig에 다음 항목을 추가합니다. 직접 열어 확인하거나 손으로 적어도 됩니다.
[safe]
directory = /home/dev/myrepo② Docker 컨테이너 빌드
컨테이너 안에서 git을 쓰는데, 빌드 컨텍스트나 마운트된 볼륨의 소유자가 호스트 UID라 컨테이너의 실행 사용자와 어긋나는 경우입니다. Dockerfile 빌드 단계에 한 줄 추가하는 게 가장 깔끔합니다.
# 작업 경로를 신뢰 디렉터리로 등록 (/workspace 등 실제 경로로 교체)
RUN git config --global --add safe.directory /workspace
# 비root 사용자로 전환해 빌드한다면, 그 사용자 컨텍스트에서 실행되도록 순서 주의
# root로 빌드하면서 마운트 소유자가 다를 때 가장 자주 재발합니다③ sudo / 다른 사용자로 clone한 repo
sudo git clone 했거나, 다른 계정으로 받아둔 리포지토리를 지금 내 계정으로 만지는 경우입니다. 이때는 신뢰 등록보다 소유권 교정이 근본 해결입니다.
# <path>를 실제 경로로 교체. 디렉터리 전체 소유자를 현재 사용자로 정렬
sudo chown -R $(whoami):$(whoami) <path>④ CI/CD(Jenkins·GitHub Actions·GitLab) 및 NFS·WSL
CI 러너 컨테이너, self-hosted 러너, NFS 마운트, WSL2의 윈도우 마운트 경로(/mnt/c/...)에서 자주 터집니다. 잡(job) 초반에 스텝 하나를 추가하세요.
# GitHub Actions 예시 — checkout 직후 한 스텝
- name: Mark workspace as safe
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"# Jenkins / GitLab 셸 스텝 또는 entrypoint
git config --global --add safe.directory "$CI_PROJECT_DIR" # GitLab
git config --global --add safe.directory "$WORKSPACE" # Jenkins참고: GitHub Actions의
actions/checkout은 기본 러너에서 이 설정을 자동으로 처리합니다. 그런데도 컨테이너 job이나 self-hosted 러너에서 다시 떠오른다면, checkout이 만든 설정과 실제 git 실행 사용자가 또 어긋난 것이니 위 스텝을 명시적으로 추가하면 됩니다.
safe.directory '*' — 편하지만 위험한 만능키
"경로마다 등록하기 귀찮은데 한 방에 안 될까?" 하면 이 명령이 보입니다.
# 모든 디렉터리를 무조건 신뢰 (강력하지만 위험)
git config --global --add safe.directory '*'⚠️ 보안 경고
safe.directory '*'는 모든 디렉터리의 소유자 검사를 통째로 끄는 설정입니다. 이는 사실상 CVE-2022-24765 방어를 비활성화하는 것과 동등합니다. 공유서버·멀티유저 빌드서버·운영 환경에서는 절대 남발하지 마세요. 타인이 심은.git/config가 내 권한으로 실행될 길을 다시 열어주는 셈입니다.
물론 균형 있게 봐야 합니다. 단일 사용자만 쓰는 격리된 1회용 CI 컨테이너처럼, 외부 침입 경로가 없고 매번 폐기되는 환경이라면 '*'이 합리적인 선택일 수 있습니다. 핵심 기준은 "이 환경에 나 말고 다른 사용자의 손이 닿는가?"입니다.
실무 경험상, 가장 사고가 잦은 패턴은 공유 빌드서버에 누군가 '*'을 박아두고 잊어버리는 것입니다. 당장은 모두가 편하지만, 나중에 그 서버에서 신뢰할 수 없는 PR 코드를 빌드하는 순간 방어선이 사라져 있죠. 그래서 저는 팀 표준을 "경로 단위 등록 + Docker 이미지에 굽기"로 잡고, '*'은 일회용 컨테이너에서만 허용하도록 PR 리뷰 체크리스트에 넣어 둡니다.
결론: 진단 표 + FAQ + 근본 처방
증상만 보고 바로 해결로 직행할 수 있게 정리했습니다.
| 에러 / 증상 | 근본 원인 | 권장 해결 |
|---|---|---|
Docker 컨테이너에서 dubious ownership | 마운트 볼륨 소유자(호스트 UID) ≠ 컨테이너 실행 사용자 | Dockerfile에 RUN git config --global --add safe.directory <path> |
sudo git clone 후 일반 계정에서 발생 | 디렉터리 소유자가 root | sudo chown -R $(whoami):$(whoami) <path> (근본 해결) |
| CI 러너(컨테이너 job·self-hosted)에서 매번 발생 | 잡마다 워크스페이스 소유자/실행 사용자 불일치 | checkout 후 safe.directory "$WORKSPACE" 스텝 추가 |
| NFS·WSL 마운트 경로에서 발생 | 네트워크/윈도우 파일시스템의 소유자 매핑이 git UID와 불일치 | 해당 절대경로를 safe.directory에 등록 |
자주 묻는 질문 (FAQ)
Q. 루트(root)로 실행하면 그냥 해결되지 않나요?
A. 됩니다. root는 소유자 검사를 우회하는 경우가 많거든요. 하지만 권장하지 않습니다. 권한 상승은 악성 .git/config가 실행될 때 피해 범위를 최대로 키우고, 빌드 산출물 소유자까지 root로 만들어 또 다른 권한 문제를 낳습니다. 원인(소유자 불일치)을 가리는 임시방편일 뿐입니다.
Q. 분명히 고쳤는데 매번 또 떠요. 왜죠?
A. 세 가지를 확인하세요. ① 설정이 --global로 들어갔는데 git을 실행하는 사용자의 HOME이 매번 달라(예: CI에서 HOME이 비어 /가 되는 경우) ~/.gitconfig를 못 읽는 경우. ② 모든 사용자에게 적용하려면 --system이 필요한데 --global로만 등록한 경우. ③ 경로가 절대경로가 아니거나 심볼릭 링크/마운트 경로가 매번 달라지는 경우. CI라면 HOME을 고정하거나 --system을 고려하세요.
Q. CI에서 영구적으로 적용하려면?
A. 두 가지 길이 있습니다. (1) 이미지에 굽기 — CI 베이스 Docker 이미지 빌드 시 RUN git config --system --add safe.directory <path>로 박아두면 모든 잡이 상속받습니다. (2) 매 잡 스텝 추가 — checkout 직후 safe.directory 설정 스텝을 넣습니다. 이미지를 관리할 수 있으면 (1)이 깔끔하고, 워크스페이스 경로가 잡마다 바뀌면 (2)가 안전합니다.
마지막으로 한 줄 행동 지침으로 닫겠습니다. 임시 처방은 safe.directory, 근본 처방은 소유권 정렬(chown / UID 일치) 입니다. 급할 땐 경로를 신뢰 목록에 넣어 5분 안에 작업을 재개하고, 여유가 생기면 컨테이너·마운트의 UID를 맞춰 에러가 다시 안 뜨게 만드세요.
이 글은 AI 에이전트가 1차 초안을 작성한 뒤, 사람 편집자가 사실관계·출처·톤과 맥락을 검토하여 발행했습니다. 오류나 부정확한 내용이 확인되면 24시간 이내에 정정합니다.
댓글
불러오는 중...