Skip to content

.env 보안 동기화 패턴

핵심 원칙

┌─────────────────────────────────────────────────┐
│  값 (secret)  →  macOS Keychain                  │
│                  + iCloud Keychain (자동 sync)    │
│                                                   │
│  키 목록 (참조) →  ainote ({project}-env-ref.md) │
│                                                   │
│  ❌ 값 자체를 ainote 에 저장 금지                 │
│  ❌ git 에 .env 커밋 금지                         │
└─────────────────────────────────────────────────┘

왜 이 분리

저장소보안동기화검색
ainote 에 값약함 (키 노출 위험)
Keychain 만강함 (OS 암호화)✅ iCloud
Keychain + ainote 참조강함✅ (참조만)

ainote 는 어떤 키가 어디 있는지만 — 실제 값은 Keychain.

스크립트 사용

~/scripts/ainote-env-sync.sh (설치 가이드).

Push: .env → Keychain + ainote 참조

bash
ainote-env-sync.sh push tennis-bracket

내부 동작:

  1. ~/tennis_bracket/.env 읽음
  2. 각 KEY=VALUE 를 security add-generic-password 로 Keychain 저장
    • service: dev-env/tennis-bracket
    • account: KEY 이름
  3. 키 목록 (이름만) 을 ainote 에 tennis-bracket-env-ref.md 로 push

Pull: Keychain → .env (새 기기)

bash
ainote-env-sync.sh pull tennis-bracket

내부 동작:

  1. ainote 에서 tennis-bracket-env-ref.md 받음 → 키 목록
  2. 각 키를 security find-generic-password 로 Keychain read
  3. ~/tennis_bracket/.env 생성

ainote 에 저장되는 형식

tennis-bracket-env-ref.md:

markdown
---
name: tennis-bracket-env-ref
type: reference
ainote_sync: env-refs/tennis-bracket-env-ref.md
last_pushed: 2026-05-07T10:00:00Z
device: macmini-2026-04
---

# tennis-bracket .env Reference

| Key | Type | Source | Note |
|-----|------|--------|------|
| RAILS_ENV | config | env | development/production |
| DATABASE_URL | secret | Keychain | postgres URL |
| TOSS_CLIENT_KEY | secret | Keychain | TossPayments client |
| TOSS_SECRET_KEY | secret | Keychain | TossPayments secret |
| FIREBASE_PROJECT_ID | config | env | tennis-bracket-app |
| AWS_ACCESS_KEY_ID | secret | Keychain | S3 |
| ... | ... | ... | ... |

값 없음. 이름 + 타입만.

새 기기 일괄 복원 (5분)

bash
# 1. iCloud Keychain 켜기 (시스템 설정)
# 2. 스크립트 받기
brew install ainote-tools

# 3. ainote 키
export AINOTE_API_KEY="..."

# 4. 일괄
ainote-env-sync.sh pull-all

응답:

✓ ~/launchcrew/.env (18 keys from Keychain)
✓ ~/tennis_bracket/.env (12 keys)
... (12 projects)

✅ 12 .env files restored

키 회전

분기마다:

bash
# 1. 새 키 발급 (서비스 사이트)
TOSS_SECRET_KEY="<NEW>"

# 2. .env 수정
$EDITOR ~/tennis_bracket/.env

# 3. push (Keychain 갱신 + ainote ref 갱신 — last_pushed 만 변경)
ainote-env-sync.sh push tennis-bracket

비밀 누출 시

bash
# 1. Keychain 즉시 삭제
security delete-generic-password -s "dev-env/tennis-bracket" -a "TOSS_SECRET_KEY"

# 2. ainote 참조에서도 표시
$EDITOR ~/tennis_bracket/.env   # KEY 자체 삭제
ainote-env-sync.sh push tennis-bracket

서비스 콘솔에서 키 폐기 + 새 발급.

등록된 프로젝트 (예시)

bash
$ ainote-env-sync.sh list

tennis-bracket   12 keys  Last sync: 2026-05-07
launchcrew       18 keys  Last sync: 2026-05-06
keeps             8 keys  Last sync: 2026-05-05
triphelper       15 keys
realpick          9 keys
talkk            14 keys
ax-admin         22 keys
ainote-app       11 keys
krx-listing      19 keys
krx-ai           13 keys
mbti-luck         7 keys
forfit            6 keys

비교: 다른 솔루션

ainote-env-sync1Password CLIdopplerdirect iCloud
iCloud Keychain✅ free
키 목록 검색✅ ainote
무료⚠️ free tier
프로젝트별 .env△ vault✅ env
자동화 친화✅ shell✅ CLI✅ CLI

다음

MIT License · ainote.dev