AI 에이전트 설정을 GitHub에 안전하게 백업하기: Hermes export와 복원 점검
Hermes profile export로 skill과 memory를 내보내고 GitHub private repository에 안전하게 백업하는 절차입니다. fine-grained token 최소 권한, 비밀값 검사, Windows 로컬 예약 내보내기와 수동 검토·원격 반영을 나눠 정리했습니다.

AI 에이전트를 VPS(클라우드에서 월 단위로 빌려 쓰는 가상 서버)에 설치하고 메신저 게이트웨이까지 연결하면 서버 안에 자료가 계속 쌓입니다. 프로필의 정체성 문서, 대화하면서 만든 skill, 에이전트가 저장한 memory가 여기에 해당합니다. 그런데 이 자료가 서버 한 대에만 있으면 컨테이너를 다시 설치할 때 함께 사라집니다.
따라서 메신저 연결까지 마쳤다면 백업도 같이 설정해야 합니다. 이번 글에서는 Hermes의 profile export로 설정을 내보낸 다음, 내용을 확인하고 GitHub private repository(비공개 저장소)에 push하는 과정을 정리합니다. 원본 영상에서 사용한 자연어 백업 방식에 현재 공식 CLI와 보안 권고를 추가했습니다. Mac mini나 로컬 mini PC에서 운영하는 경우에도 백업 원칙은 같습니다.

사용 도구 및 준비물
1단계. private repository 만들기
GitHub에 가입한 계정에서 새 repository를 하나 만듭니다. 이름은 본인이 알아볼 수 있는 수준이면 충분합니다. public이 아니라 private으로 만듭니다. 빈 저장소로 시작하면 첫 push 충돌을 줄일 수 있지만 필수 조건은 아닙니다. private 저장소도 비밀 보관소는 아니므로 API 키를 올려서는 안 됩니다.

2단계. 프로필 Settings에서 fine-grained token 발급하기
여기서 repository 안에 있는 Settings로 들어가면 안 됩니다. GitHub 우측 상단의 프로필을 누르고 계정 Settings로 들어갑니다. 좌측 메뉴를 끝까지 내리면 Developer Settings가 나옵니다. personal access token 발급 메뉴에서 Fine-grained tokens를 선택하고 Generate new token을 누르면 계정 인증 화면이 표시됩니다.
인증이 끝나면 token 이름을 입력합니다. 저는 어떤 서버에서 사용하는 백업 키인지 바로 알 수 있도록 서버 이름과 backup key를 함께 적었습니다. token이 여러 개 생겼을 때 이름만 보고 용도를 확인할 수 있어야 관리하기 쉽습니다.
만료 기간은 실제로 갱신을 관리할 수 있는 가장 짧은 기간으로 둡니다. 개인 운영이라면 30~90일로 시작하고 갱신 일정을 캘린더에 등록하는 편을 권합니다. No expiration은 GitHub가 허용하더라도 키가 유출됐을 때 자동으로 끊기는 안전장치가 없어 기본값으로 추천하지 않습니다.

3단계. token 권한을 저장소 한 곳으로 제한하기
fine-grained token의 접근 범위는 백업할 저장소 한 곳으로 제한합니다. 여기서 설정할 항목은 두 가지입니다.
| 항목 | 설정값 | 이유 |
|---|---|---|
| Repository access | Only select repositories → 1단계에서 만든 저장소만 선택 | 다른 저장소는 이 키로 건드릴 수 없게 차단 |
| Permissions → Contents | Read and write | 백업 내용을 원격 저장소에 push하려면 필요 |
Contents를 Read-only로 설정하면 로컬 commit은 만들 수 있지만 원격 push는 할 수 없습니다. 백업에는 Read and write가 필요합니다. 그 외의 권한은 추가하지 않습니다.
Generate token을 누르면 키 값이 한 번 표시됩니다. 화면을 벗어나면 다시 볼 수 없으니 그 자리에서 복사해 안전한 곳에 옮겨 둡니다. 이 값은 어떤 경우에도 노출하면 안 됩니다. 스크린샷, 화면 공유, 캡처본 공유 모두 포함입니다.

4단계. Git 인증은 에이전트 프롬프트와 분리하기
토큰 값을 프롬프트에 붙여 넣거나 평문 CLI 인수로 넘기지 않습니다. GitHub CLI의 보안 입력이나 OS credential manager를 사용해 대상 저장소 인증을 별도로 구성합니다. 원본 영상의 hermes config set GITHUB_TOKEN ... 명령은 현재도 존재하지만, 해당 값은 Hermes 모델 인증 후보로도 쓰이고 셸 기록이나 화면 공유에 남을 수 있어 백업 인증의 기본 경로로 권하지 않습니다.
이미 그 명령을 사용했다면 셸 기록과 Hermes .env 파일 권한을 확인하고, 노출 가능성이 있으면 토큰을 즉시 폐기한 뒤 새로 발급합니다.
5단계. profile export로 첫 백업 만들기
현재 Hermes 공식 CLI에는 프로필의 skills, memory, persona, crons, plugins, settings를 내보내는 명령이 있습니다.
hermes profile export <프로필명>
<프로필명>을 실제 백업 대상 프로필로 바꿉니다. 이 export는 API 키를 제거하도록 설계되어 있지만 자동 처리를 맹신하지는 않습니다. 생성된 아카이브의 파일 목록과 내용을 검사한 다음, 허용한 파일만 저장소 작업 폴더에 넣고 commit·push합니다. 세션과 인증 정보까지 포함할 수 있는 hermes backup 결과물은 GitHub에 평문으로 올리지 말고 암호화된 별도 스토리지에 보관합니다.

6단계. Windows에서 내보내기와 원격 반영 나누기
아래 예제는 Windows PowerShell·Git·GitHub CLI·Hermes가 설치된 PC 기준입니다. backup-demo와 저장소 주소는 실제 값으로 바꿔야 합니다. 2026-09-16에 설치된 Hermes v0.20.5의 export/import 도움말에서 --output, --name 옵션을 확인했습니다. 운영 프로필의 실제 export·업로드를 대신 실행한 기록은 아닙니다.
먼저 수동으로 한 번 확인
GitHub 인증은 브라우저 로그인과 Git credential helper로 설정합니다. 토큰 값을 명령에 적지 않습니다. gh auth login에서 Git 인증 설정에 동의하거나 이미 로그인한 뒤 gh auth setup-git을 실행합니다. 앞에서 만든 비공개 저장소를 사용하세요.
gh auth login
gh auth setup-git
git clone https://github.com/YOUR_ACCOUNT/YOUR_PRIVATE_BACKUP.git C:\agent-backup-repo
New-Item -ItemType Directory -Force C:\agent-backup-staging | Out-Null
hermes profile list
hermes profile export backup-demo --output C:\agent-backup-staging\backup-demo.tar.gz
tar -tf C:\agent-backup-staging\backup-demo.tar.gz
아카이브는 저장소 밖에 둡니다. 목록을 확인한 뒤 새 검토 폴더에 풀고 설정 파일뿐 아니라 memory·skill 본문까지 직접 읽습니다. API 키 자동 제거 기능은 본문에 적어 둔 고객 정보까지 지워준다는 보장이 아닙니다.
New-Item -ItemType Directory -Force C:\agent-backup-review | Out-Null
tar -xf C:\agent-backup-staging\backup-demo.tar.gz -C C:\agent-backup-review
Get-ChildItem C:\agent-backup-review -Recurse -File
API 키·비밀번호·개인정보가 없는 것을 확인한 아카이브만 저장소로 복사합니다. 포함하면 안 되는 정보가 있다면 업로드하지 말고 원본 프로필의 저장 방식을 고친 뒤 다시 내보내세요. 압축파일은 git diff로 본문을 읽을 수 없으므로 위 검토를 건너뛸 수 없습니다.
New-Item -ItemType Directory -Force C:\agent-backup-repo\snapshots | Out-Null
Copy-Item C:\agent-backup-staging\backup-demo.tar.gz C:\agent-backup-repo\snapshots\backup-demo.tar.gz
Set-Location C:\agent-backup-repo
git add -- snapshots/backup-demo.tar.gz
git diff --cached --stat
git status --short
git commit -m "chore: save reviewed profile backup"
git push
git rev-parse HEAD
git ls-remote origin HEAD
처음 clone한 기본 브랜치에서 실행하는 예제입니다. 마지막 두 명령의 커밋 ID가 일치하는지 확인하세요. 다른 브랜치에 push했다면 git ls-remote origin refs/heads/브랜치명으로 해당 브랜치를 비교합니다.
로컬 정기 export
예약 실행용 PowerShell 스크립트를 C:\agent-backup-tools\export-profile.ps1로 저장합니다. 이 스크립트는 로컬 아카이브와 해시 기록만 만들고 GitHub로 전송하지 않습니다. 변경 내용을 확인하지 않은 채 자동 push하는 예제는 아닙니다.
터미널에서 먼저 실행합니다. HermesCommand에는 Get-Command hermes로 확인한 실행 파일의 전체 경로를 넣습니다.
Get-Command hermes | Select-Object Source
powershell.exe -NoProfile -File C:\agent-backup-tools\export-profile.ps1 -Profile backup-demo -Destination C:\agent-backup-staging -HermesCommand "C:\실제설치경로\hermes.exe"
작업 스케줄러의 ‘작업 만들기’에서 같은 Windows 계정으로 등록합니다.
| 항목 | 입력 예시 |
|---|---|
| 트리거 | 매일 21:00 — 운영 시간에 맞게 변경 |
| 프로그램 | powershell.exe |
| 인수 | -NoProfile -File C:\agent-backup-tools\export-profile.ps1 -Profile backup-demo -Destination C:\agent-backup-staging -HermesCommand "C:\실제설치경로\hermes.exe" |
| 시작 위치 | C:\agent-backup-tools |
| 중복 실행 | 새 인스턴스를 시작하지 않음 |
| 확인 | ‘실행’으로 시험한 뒤 마지막 실행 결과 0과 새 .tar.gz.json 기록 확인 |
조직의 스크립트 실행 정책이 차단하면 관리자에게 서명된 실행 방법을 확인합니다. 예제는 실행 정책을 우회하지 않습니다. 실행 계정이 다르면 같은 프로필을 찾지 못할 수 있습니다.
JSON에는 내보낸 시각·파일 크기·SHA-256과 remoteUploaded: false, contentReviewed: false가 기록됩니다. 이 값은 원격 백업 성공을 뜻하지 않습니다. 검토한 스냅샷만 위 수동 절차로 올리고, 로컬 보관함이 계속 커지지 않도록 보관 기간도 정하세요.
7단계. 백업에 포함된 파일 확인하기
백업 작업이 끝나면 완료 메시지만 보지 말고 GitHub 저장소와 push 전 diff를 직접 확인합니다. 다음 네 항목을 차례로 봅니다.
- memory가 반영되었는지
- skill 목록에 내장 skill뿐 아니라 직접 만든 skill이 들어와 있는지
- crons, plugins, settings 등 복구에 필요한 운영 정보가 들어왔는지
- API key, token, password,
.env문자열이 포함되지 않았는지
제가 확인했을 때는 메신저에서 대화하며 만들어 둔 개인 skill이 export 결과에 들어왔습니다. 하지만 에이전트가 민감 정보를 알아서 제외한다고 가정하면 안 됩니다. GitHub도 private 저장소를 포함해 암호화되지 않은 키를 push하지 말라고 권고합니다. 첫 백업뿐 아니라 자동화 경로에서도 스테이징 목록과 diff를 검사하고, 의심되는 값이 하나라도 있으면 push를 중단해야 합니다.

제 VPS의 백업 봇은 실제로 이렇게 돌고 있습니다
위 절차는 처음 백업을 만드는 분께 권하는 순서라 "검토한 스냅샷만 수동으로 push"를 기본으로 잡았습니다. 솔직히 적으면 제 VPS의 Hermes는 지금 매일 자동으로 커밋하고 push합니다. 사람이 하던 확인을 스크립트 안에 넣어 두고 자동으로 돌리는 방식입니다. 그래서 실제 운영 기록을 공개하고, 자동으로 돌리려면 무엇을 갖춰야 하는지 실물로 보여드리겠습니다.

백업 저장소(private)의 커밋 270건을 날짜별로 센 그래프입니다. 커밋 작성자는 전부 "Hermes Backup Bot"이고, 메시지는 chore: backup Hermes profile state (2026-10-02 06:00:56 UTC) 같은 한 줄입니다. 118일 중 커밋이 없는 날은 5일뿐이었습니다. 하루 13건이 대부분이고, 시각으로는 한국 시간 자정새벽 1시대에 144건이 몰려 있습니다. 바뀐 내용이 없으면 커밋 자체를 만들지 않기 때문에 날마다 건수가 다릅니다.
저장소 맨 위에는 다음만 있습니다. 2026-10-02 기준 파일 956개, 그중 SKILL.md가 116개입니다.
.gitignore
MANIFEST.tsv ← 파일마다 경로·크기·sha256 앞 16자리
README.md ← 무엇이 들어 있고 무엇을 뺐는지
profile/
cron/ memories/ scripts/ skills/
status/
자동으로 돌리면서 사람 대신 확인하는 장치는 백업 스크립트(hermes_github_backup.py, 386줄) 안에 있습니다. 핵심은 두 겹입니다. 첫째, 파일을 저장소에 쓰기 전에 줄마다 키 이름과 값 모양을 보고 가립니다.
def redact_text(text: str) -> str:
lines: list[str] = []
for line in text.splitlines():
if re.match(r"\s*[A-Za-z0-9_.-]+\s*[:=]", line): # "이름: 값" 또는 "이름=값" 줄이면
...
key = line[: line.find(sep)]
if SECRET_KEY_RE.search(key): # 이름에 token·secret·password·api_key 등이 있으면
line = line[: line.find(sep) + 1] + ' "[REDACTED]"'
for rx in SECRET_VAL_RE: # 값이 sk-..., ghp_..., xox..., 개인키 블록처럼 생겼으면
line = rx.sub("[REDACTED_SECRET]", line)
lines.append(line)
return "\n".join(lines) + "\n"
둘째, 커밋 직전에 저장소 전체를 다시 훑어 키 모양 문자열이 하나라도 남아 있으면 커밋과 push를 하지 않고 실패로 끝냅니다.
hits = secret_scan()
if hits:
raise RuntimeError("secret scan failed: " + ", ".join(hits[:20]))
.env 원본, OAuth 토큰 파일, 세션 DB, 대화 기록, 전체 로그는 처음부터 복사하지 않고, .env는 키 이름만 profile/env.keys에 남깁니다. push에 쓰는 GitHub 토큰은 프로필 .env에서 읽어, 실행 중에만 임시 파일로 만들었다가 push가 끝나면 지웁니다. 위 4단계에서 권한 분리를 권한 것과 다른 지점이라, 이렇게 운영하신다면 그 토큰만큼은 2~3단계처럼 백업 저장소 하나에 Contents 권한만 준 짧은 만료 토큰으로 묶어 두셔야 합니다.
이 정도를 갖춘 뒤에 자동으로 돌렸지만, 이번에 글을 고치면서 백업된 파일을 직접 열어보다가 문제를 하나 찾았습니다. 백업 저장소에 들어간 백업 스크립트 자신이 가림 처리에 걸려 있었습니다.
SECRET_KEY_RE = "[REDACTED]"
r"(?i)(api[_-]?key|token|secret|password|passwd|credential|...)"
)
원래는 SECRET_KEY_RE = re.compile(...)인 줄인데, 이름에 SECRET이 들어 있고 =가 있으니 비밀값 줄로 판단해 오른쪽을 지워버렸습니다. 같은 이유로 386줄 중 7줄이 "[REDACTED]"로 바뀌었고, 백업본을 그대로 실행하면 IndentationError로 멈춥니다. 비밀값은 하나도 새지 않았으니 가림 처리는 제 역할을 한 셈인데, 대신 백업에서 복원한 스크립트는 돌아가지 않습니다. 위에서 "복원해 보기 전에는 백업 완료로 보지 않는다"고 쓴 이유가 제 저장소에서 그대로 나왔습니다.
자동으로 돌리시려면 그래서 세 가지를 권합니다. 가림 규칙과 커밋 직전 검사를 스크립트에 넣을 것, 검사에 걸리면 push 자체를 멈추게 할 것, 그리고 가끔은 백업본을 실제로 받아 열어보고 복원 리허설을 할 것.
복원해 보기 전에는 백업 완료로 보지 않기
저장소에 파일이 올라갔다고 해서 원래 작업 환경까지 복원할 수 있다는 뜻은 아닙니다. 첫 백업을 만든 뒤에는 운영 프로필과 분리된 시험용 환경에서 복원 과정을 확인합니다. 순서는 다음과 같습니다.
- 복원할 백업의 커밋 ID와 생성 시각을 적습니다. 필요한 시점의 파일인지 확인할 기준입니다.
- 별도 폴더에 백업을 받아 파일 목록을 비교합니다. 운영 폴더에 바로 덮어쓰지 않습니다. 아카이브 전체를 보관했다면 설치된 버전의 공식 profile import 절차를 확인합니다. 일부 파일만 Git으로 보관했다면 전체 프로필 아카이브처럼 가져올 수는 없습니다.
- 시험용 환경에서는 메신저 연결과 예약 작업을 켜지 않습니다. 복원 검증이 운영 작업을 중복 실행하지 않게 하기 위해서입니다. 인증 정보는 백업 파일 대신 기존의 안전한 인증 경로에서 별도로 설정합니다.
- 직접 만든 skill 하나와 민감하지 않은 memory 항목 하나를 골라 내용이 같은지 비교합니다. 파일이 존재해도 다른 버전의 설정 형식 때문에 로드에 실패할 수 있으므로 실제로 읽히는지까지 확인합니다.
- 성공 여부와 빠진 항목을 기록합니다. 빠진 파일은 다음 백업의 허용 목록에 넣을지, 인증 정보처럼 별도로 복구할 대상인지 나눕니다.
다른 PC나 격리된 시험 환경에 검토한 아카이브를 받아 다음처럼 새 이름으로 가져옵니다. backup-rehearsal은 기존에 없는 이름이어야 합니다. import 전에 설치 버전의 hermes profile import --help를 확인하세요.
hermes profile import C:\agent-backup-staging\backup-demo.tar.gz --name backup-rehearsal
hermes profile show backup-rehearsal
가져온 파일에서 직접 만든 skill 하나와 memory 항목 하나를 원본과 비교하고, 예약 작업·채널 상태를 확인한 뒤 필요한 동작만 시험합니다. show 출력만으로 skill 실행까지 검증한 것은 아닙니다.
| 증상 | 먼저 확인할 곳 | 대응 |
|---|---|---|
| 로컬 커밋만 최신이고 GitHub는 오래됨 | 마지막 push 결과, 토큰 만료, 대상 저장소 권한 | 원인을 해결한 뒤 원격 커밋 ID까지 확인 |
| 백업에는 있는데 skill을 못 읽음 | 프로필 선택, 파일 위치, 설치 버전 | 시험 환경에서 로딩 경로를 바로잡고 다시 확인 |
| 예약 작업이 두 번 실행됨 | 원본과 복원 환경의 예약·게이트웨이 상태 | 시험 환경의 실행을 멈추고 운영 인스턴스를 하나로 정리 |
“백업 성공” 알림과 별개로 마지막 성공 시각을 확인하는 이유도 여기에 있습니다. 작업 자체가 실행되지 않으면 실패 알림도 오지 않을 수 있습니다. 백업 파일, 원격 반영, 복원 가능성을 따로 확인해야 누락된 단계를 찾을 수 있습니다.
개인적인 생각
저는 로컬 mini PC와 VPS 두 곳에서 에이전트를 동시에 운영하고 있습니다. 설치 파일은 명령어 몇 줄로 다시 받을 수 있지만, 몇 주 동안 대화하면서 만든 skill과 그 사이에 쌓인 memory는 따로 백업하지 않으면 복구할 수 없습니다. 그래서 이 글에서는 직접 쌓인 자료인 memory, skill, 채널 manifest를 백업 대상으로 정했습니다.
읽는 분 상황에 따라 판단이 갈릴 지점도 짚어 두겠습니다. 개인 실험 환경도 저장소 하나 + Contents Read and write + 30~90일 만료 조합으로 시작할 수 있습니다. 팀 계정이나 회사 organization 아래에서는 조직 정책이 더 짧은 만료 기간이나 승인을 요구할 수 있습니다. token 하나가 새어 나갔을 때 접근 범위와 생존 시간이 모두 제한되어 있어야 합니다.
한계도 적어 둡니다. 이 글의 GitHub 화면 순서, 권한 항목명, Hermes 명령어는 모두 작성일 기준입니다. GitHub 쪽 UI는 안정적인 편이지만 메뉴 이름이 바뀌는 경우가 종종 있고 에이전트 명령어는 버전에 따라 달라집니다. 발행 시점의 최신 버전에서 명령어가 그대로 동작하는지 한 번 재검증이 필요합니다.
다음 글 예고 & Reference
에이전트 운영에서 백업 다음으로 자주 터지는 지점은 모델 쪽입니다. 프로바이더 서버가 죽거나 플랜이 만료되면 에이전트가 그 자리에서 멈춥니다. 다음 글에서는 OpenRouter를 붙여 폴백 체인을 구성하는 방법을 다루겠습니다.
Reference
추가 학습 자료 신청
ZEXEA 메인 사이트의 자료 신청 페이지로 이동합니다. 이름·이메일·전화번호 등의 입력이 필요합니다. 블로그 글과 실습 예제는 신청 없이 모두 읽을 수 있습니다.
관련 가이드
Hermes에 OpenRouter 폴백 연결하기: 대체 모델 설정과 장애 검증 절차
OpenRouter를 Hermes의 장애 대비 후보로 연결하는 방법입니다. 충전·무료 모델의 데이터 정책, turn 단위 폴백 동작, 운영 전 검증 항목까지 정리했습니다.
전체 과정 보기
CLAUDE.md, 잘 쓰고 있는지 5가지 기준으로 진단하세요 (복붙용 개선 프롬프트 포함)
CLAUDE.md가 방치되는 이유는 관리 플러그인이 없어서가 아니라 진단이 없어서입니다. 프로젝트 지도부터 실행 모델까지 5가지 판정 기준과 200줄 룰 구조 점검, 그리고 진단에서 개선 실행까지 한 번에 굴리는 3-Phase 프롬프트 전문을 정리했습니다.
전체 과정 보기Claude Code 프론트엔드 디자인 도구 5종, AI 티 나는 웹사이트를 고치는 스킬·CLI 사용법
Claude Code로 만든 웹사이트의 AI 티를 줄이는 디자인 도구 5종. Awesome DESIGN.md, Taste Skill, Image to Code, Playwright CLI, Vercel 규칙 스킬의 정체와 설치법, 쓰는 시점, 직접 돌려본 결과를 정리했습니다.
전체 과정 보기