Skip to Content

Secret Rotation

AI 요청 프롬프트

https://docs.axelabs.ai/ops/runbook/secret-rotation 따라 [secret name] 회전 진행해줘. 진행: 1. 회전 대상 secret + provider 식별 (Azure / Meta / Naver / GitHub / Anthropic / 기타) 2. Azure 면 az cli 6 단계 분기, 그 외면 `axe secret rotate <ENV_NAME>` interactive 분기 3. 페이지의 각 step 명령 실행 + 검증, 매 step 결과 받고 다음. 특히 OLD secret revoke 직전 사용자 확인 (NEW secret 무중단 swap + production 검증 통과 후) 4. 함정 발생 시 페이지 본문 따라 우회 (App Owner 부재 / external portal 수동 / `unset NEW` shell history 정리 / merge-mode pull 누락) 5. 회전 완료 + production health 검증 + (선택) /ops/updates Ship Log 한 줄

본인 AI session = Claude Code / Cursor / ChatGPT 데스크탑 / Claude.app / 기타.

페이지 본문 = 사람이 직접 read 도 가능, AI 도 참고. AI 가 본 페이지 fetch 후 위 진행 순서대로 사용자와 step-by-step interactive 풀어나감.

D-ops-17 + D-ops-19 (2026-05-21) 이후 표준: Azure 의 client_secret 은 az cli 6 단계 로 portal UI 0회. 다른 provider (Meta/Naver/GitHub/Anthropic) 는 axe secret rotate 의 interactive 경로 + 외부 portal 수동.

Azure 회전 — az cli 6 단계 (권장)

APP_ID=137fc0ef-eb9f-4903-acbc-1a748add349c # frame_mcp (예시) OLD_KEY_ID=$(az ad app credential list --id $APP_ID \ --query "[?starts_with(hint,'<old prefix>')].keyId | [0]" -o tsv) # 1. Azure 새 secret 추가 — --append 가 OLD 유지 = overlap window NEW=$(az ad app credential reset --id $APP_ID \ --display-name "auto-rotated 2026-MM-DD" --years 2 --append \ --query password -o tsv) # 2. vault PUT axe secret push AZURE_FRAME_MCP_CLIENT_SECRET --service frame --value "$NEW" # 3. pull (merge-mode — config 보존) axe secret pull frame # 4. 무중단 swap axe deploy frame axe --apply # frame / hive axe blueprint upgrade axe --apply # blueprint # 5. 검증 docker exec $(active container) env | grep AZURE_FRAME_MCP_CLIENT_SECRET /usr/bin/curl -sI https://axe.axelabs.ai/frame/health # 200 # 6. OLD revoke (검증 후) az ad app credential delete --id $APP_ID --key-id $OLD_KEY_ID unset NEW # shell history 에서 제거

전제조건 — App Owner 확인

az ad app credential reset 은 app 의 owner 만 가능. portal-등록 app 은 default 로 owner 없음:

az ad app owner list --id $APP_ID --query "[].userPrincipalName" -o tsv # 비어 있으면 → portal 에서 owner 추가 후 재시도: # open "https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Owners/appId/$APP_ID"

본 플랫폼의 모든 AXE app 은 [email protected] owner 박혀 있음 (2026-05-21 audit). 신규 az cli 등록 app 은 호출자가 owner 자동 박힘.

다른 provider 회전 — axe secret rotate interactive

Anthropic / GitHub / Meta / Naver / Slack 등 az 안 통하는 provider:

axe secret rotate <ENV_NAME> --service <svc>

진행:

  1. 매니페스트의 rotation_external 확인 → provider portal URL 출력
  2. 운영자가 portal 에서 새 값 발급 → 복사 → 프롬프트에 붙여넣기 (getpass, 화면 안 보임)
  3. vault PUT
  4. axe secret pull SVC (merge-mode)
  5. axe ship SVC 트리거 (working tree dirty 면 abort — axe deploy ... --apply 로 수동 보완)
  6. 운영자가 provider 에서 OLD 수동 revoke

상세 데이터 흐름: /architecture/secrets.

회전 주기 — 정기 점검

Microsoft Entra ID app 의 client_secret 회전 주기 = 24개월 (Frame MCP), 180일 (Blueprint, Vaultwarden).

만료 30일 전 자동 알림. 미루지 말 것 — 만료 = OAuth 전체 마비.

사전 알림

현재 상태: com.axe.secret-check launchd 자동 알림 + axe secret status --customer X CLI 는 향후 추가 예정 (TODO). 현재는 수동 확인:

# 운영자 콘솔 (admin.axelabs.ai) 에 secret 만료일 표시 — `axe console rebuild` 가 매시 갱신 # 또는 Vault 에 보관된 메타에서 직접 확인: bw get item "Frame MCP — claude.ai connector secret" # 만료일 필드 확인

출력 예:

axe customer: blueprint: expires 2026-08-15 (89 days) vaultwarden: expires 2026-09-01 (106 days) frame_mcp: expires 2028-05-19 (730 days)

90일 이내면 운영자 콘솔 dashboard 에 빨간 배너.

회전 절차 (180일 secret, ~30분)

예: customer axeframe_mcp secret 회전 (24개월 만료).

1. 새 secret 발급 (customer IT 측)

customer IT 에게 메일:

제목: [AXE Labs] Frame MCP client_secret 갱신 요청 (만료 30일 전) 안녕하세요, 귀사 Microsoft Entra ID 의 'Frame MCP' app 의 client_secret 이 30일 후 만료됩니다 (2028-05-19). 다음 절차로 새 secret 발급 + 안전 채널로 전달 부탁드립니다: 1. Azure portal → Microsoft Entra ID → App registrations → 'Frame MCP' 2. Certificates & secrets → + New client secret 3. Description: frame-mcp-axe-2028-05 4. Expires: 24 months 5. Add → VALUE 즉시 복사 6. Bitwarden Send (view-once, `-a 1 -d 1`) 또는 안전 채널로 운영자에게 전달 — 절차: [/architecture/secrets § 사람에게 전달](/architecture/secrets#사람에게-전달--bitwarden-send) 운영자 측 swap 완료 후 기존 secret 은 안전하게 폐기됩니다. 감사합니다. 액스코퍼레이션 주식회사 (운영 주체, [email protected])

2. 새 secret 받으면

# Keychain push (replace 기존) security add-generic-password -a axe -s "axe.axe.frame.client_secret" -w '&lt;new_value&gt;' -U # Verify security find-generic-password -s "axe.axe.frame.client_secret" -w # → &lt;new_value&gt; 출력되면 OK

3. 컨테이너 재기동 (env reload)

cd /Users/axe/frame set -a && source .env.local && set +a docker compose up -d --force-recreate frame-mcp-blue frame-mcp-green sleep 5 # Verify env 적용 docker exec frame-mcp-blue env | grep AZURE_FRAME_MCP_CLIENT_SECRET | head -c 30 # → 새 값의 prefix 보이면 OK

⚠️ 다운타임 ~3초--force-recreate 가 blue+green 동시 재기동. 향후 blue→green→blue 순차 재기동으로 0초 만들 예정 (D-ops-16 후보).

4. claude.ai connector 측 영향

frame_mcp secret 의 경우 직원 측 영향 있음:

  • claude.ai 의 Custom Connector 에 입력한 secret 도 갱신 필요
  • 운영자 → 직원들에게 새 secret 전달 (안전 채널)
  • 직원 각자 claude.ai 의 connector 편집 → Advanced 의 OAuth Client Secret 교체 → Save

⚠️ 이게 secret 회전의 가장 큰 운영 부담. 직원이 많을수록 painful. 향후 OAuth proxy 패턴 (D-ops-15) 으로 secret 분배 제거 검토.

5. 기존 secret 폐기 (24시간 후)

새 secret 활성 확인 + 직원 전원 swap 완료 후:

# customer IT 에게: "기존 client_secret (<처음 4글자만 hint, 예: XX.X~ 처럼 식별 가능한 prefix>) Azure portal 에서 삭제 부탁드립니다. 새 secret 으로 swap 완료 + 24시간 검증 완료했습니다."

⚠️ secret VALUE 평문을 docs/메일/채팅 어디에도 적지 마세요. 식별 hint 는 Azure portal 의 secret 표에서 보이는 hint prefix (보통 처음 3-4자 + ”…”) 만 사용. 운영자 본인이 회전 시점에는 Keychain find-generic-password 로 prefix 확인.

customer IT 측에서 Azure portal → Certificates & secrets → 기존 secret 옆 휴지통 클릭.

6. 검증

# customers.yaml 메타 업데이트 (선택) # sso.apps.frame_mcp.client_secret_env 의 만료일 주석 갱신 # Audit (TODO: `axe secret status` 추가 후) # 현재는 Vault item 의 만료 메타 갱신 + 운영자 콘솔 dashboard 확인

함정

함정결과회피
만료일 잊고 24시간 후 마비OAuth 전체 다운매일 자동 알림 + 30일 전 작업
새 secret swap 전 기존 삭제OAuth 즉시 다운24시간 grace period
Keychain replace 안 하고 새로 addduplicate, 어떤 게 active 인지 모름-U 플래그로 update
컨테이너 restart 만 (—force-recreate X)env file 재로드 안 됨up -d --force-recreate
직원에게 secret 일괄 push 잊음직원들 connector 실패swap 전에 communication

응급: secret 노출 의심

평문이 어딘가 노출된 의심이 있을 경우 (메일 전송 사고, 노트북 분실 등):

  1. customer IT 에게 즉시 새 secret 발급 요청 (정상 절차 X, 비상)
  2. 받자마자 Keychain push + 컨테이너 재기동
  3. 기존 secret 즉시 삭제 (24시간 grace X)
  4. audit_log 검사 — 의심 시간대에 비정상 access 있는지
  5. 직원 전원에게 알림 + claude.ai connector 즉시 update 요청

상세: Runbook · Secret 노출 대응 (예정).

Last updated on