AI 에이전트가 작업 파일을 분석하도록 설정하는 과정에서 macOS TCC 권한 문제에 반복적으로 막혔다.
Full Disk Access를 부여하지 않으면서도 안정적으로 파일을 읽게 하려면, 에이전트가 접근 가능한 디렉터리에 파일을 두되 Obsidian에서도 편하게 편집할 수 있어야 했다.
그래서 심볼릭 링크를 사용했다.
/Users/igeonseon/obsidian/work/analysis -> /Users/igeonseon/private-data
문제는 이 구조가 Git 저장소 안에 있다는 점이었다.
work 디렉터리를 Git으로 관리하는데, 민감한 데이터가 담긴 private-data가 원격 저장소로 올라가면 안 된다.
심볼릭 링크로 연결된 외부 디렉터리는 Git에 어떻게 인식될까?
역할: 파일 시스템에서 다른 경로를 가리키는 포인터
역할: 작업 트리의 파일 내용을 스냅샷으로 저장
Git은 .git 디렉터리 내부에 파일 내용을 객체로 저장한다. 일반 파일은 내용 전체를, 심볼릭 링크는 링크가 가리키는 "경로 문자열"만을 저장한다.
역할: 앱의 사용자 데이터 접근을 통제하는 보안 프레임워크
Downloads, Documents, Desktop 등 특정 폴더는 앱이 접근하기 전에 명시적 권한이 필요하다.
하지만 사용자가 직접 만든 폴더(~/dev, ~/work 등)는 TCC 보호 대상이 아니다.
/Users/igeonseon/obsidian/work/ (Git 저장소)
└── analysis -> /Users/igeonseon/private-data
work는 Git으로 관리하고, private-data는 TCC 비보호 영역에 두어 AI 에이전트가 자유롭게 읽을 수 있게 했다. 그리고 Obsidian에서는 work/analysis를 통해 편집한다.
cd /Users/igeonseon/obsidian/work
git add analysis
git commit -m "add analysis"
이때 예상과 달리 private-data 내부 파일은 Git 객체로 추가되지 않았다.
$ git ls-tree HEAD
100644 blob abc123... README.md
120000 blob def456... analysis
심볼릭 링크는 파일 모드 120000으로 저장된다. 실제 내용을 확인하면:
$ git show HEAD:analysis
/Users/igeonseon/private-data
Git은 링크가 가리키는 경로 문자열만 저장했다.
1. git add analysis
↓
2. Git이 파일 타입 확인 → 심볼릭 링크 감지
↓
3. 링크가 가리키는 경로 문자열만 읽음
↓
4. 해당 문자열을 blob 객체로 저장 (모드 120000)
↓
5. 결과: 외부 데이터는 Git에 포함되지 않음
Git은 심볼릭 링크를 따라가지 않는다.
TCC 우회: AI 에이전트가 권한 문제 없이 파일 읽기 가능
편집 편의성: Obsidian에서 work/analysis 경로로 자연스럽게 수정
보안 유지: Git 원격 저장소에 민감한 데이터 절대 노출 안 됨
심볼릭 링크 = 경로 문자열만 저장하는 포인터 (실제 데이터 X)
Git 추적 = 링크 자체만 저장, 링크 대상은 절대 추적 안 함
TCC 우회 = 사용자 생성 디렉터리는 보호 대상 제외