Cert Mirror — API 레퍼런스
base URL: https://api.ainote.dev
전체 개요는 overview 참조.
인증
모든 엔드포인트는 Authorization: McpKey <token> 헤더 필수. <token> 은 본인 ainote 계정의 UserMirrorCredential#token (64 hex chars, deterministic encrypted).
발급 — 계정당 1개
본인 ainote 계정의 primary API key (UserMcpKey 또는 User.api_key) 로 발급 endpoint 를 호출합니다. 결과 token + hmac_secret 을 클라이언트 쪽 secret store (macOS Keychain, 1Password, OS env 등) 에 보관.
권장: CLI 스크립트
ainote-cert-mirror issue자세한 셋업은 setup-guide + cli.
Raw HTTP (Linux/CI 환경)
curl -fsSL -X POST https://api.ainote.dev/api/cert_mirror/credentials \
-H "User-Agent: ainote-cli/1.0" \
-H "Authorization: McpKey <UserMcpKey-OR-api_key>" \
-H "Content-Type: application/json" \
-d '{}'응답 (신규 발급):
{
"status": "created",
"token": "<64 hex>",
"hmac_secret": "<64 hex>",
"message": "Save hmac_secret now — it cannot be retrieved later."
}응답 (이미 존재, rotate 안 함):
{
"status": "existing",
"token": "<64 hex — 동일 값>",
"hmac_secret": null,
"message": "Credential already exists. Pass rotate=true to issue new secrets ..."
}rotate=true 시 destroy + 재생성 — 기존 blob 들 HMAC 검증 실패 → 재업로드 필요.
Raw HTTP — 폐기
curl -fsSL -X DELETE https://api.ainote.dev/api/cert_mirror/credentials \
-H "User-Agent: ainote-cli/1.0" \
-H "Authorization: McpKey <UserMcpKey-OR-api_key>"두 값의 차이
| 필드 | 암호화 | 재조회 | 용도 |
|---|---|---|---|
token | deterministic | ✅ 동일 값 반환 | Authorization: McpKey <token> 인증 |
hmac_secret | non-deterministic | ❌ 발급 시점에만 평문 노출 | 업로드 시 body HMAC-SHA256 계산. 반드시 별도 보관 |
hmac_secret 회전 시 모든 기존 blob 의 signature 검증이 깨지므로 전체 cert mirror 재업로드 필요.
User-Agent (필수)
Render edge WAF 가 default curl/* 또는 Ruby UA 를 차단합니다. 모든 요청에 명시:
User-Agent: ainote-fastlane-mirror/1.0(이름 자유 — <your-tool>/<version> 형식이면 됨)
빠지면 응답:
HTTP/1.1 403
{"error":"Forbidden. Your request has been blocked."}POST /api/cert_mirror
새 cert tarball 업로드.
요청
POST /api/cert_mirror HTTP/1.1
Host: api.ainote.dev
Authorization: McpKey <token>
User-Agent: ainote-fastlane-mirror/1.0
Content-Type: application/octet-stream
Content-Length: <size>
X-Commit-Sha: <40 hex chars — apple-certs git HEAD>
X-Tarball-Sha256: <64 hex chars — body 의 SHA-256>
X-Mirror-Signature: sha256=<64 hex chars — HMAC-SHA256(hmac_secret, body)>
X-Uploaded-By: <자유 라벨, 예: "fastlane:seunghan">
<binary tarball body>헤더 표
| 헤더 | 필수 | 설명 |
|---|---|---|
Authorization | ✅ | McpKey <token> |
User-Agent | ✅ | WAF 회피 (위 참조) |
Content-Type | ✅ | application/octet-stream (멀티파트 금지 — HMAC 비트 정확 매칭) |
Content-Length | ✅ | body 바이트 수. 50 × 1024 × 1024 초과 시 즉시 413 |
X-Commit-Sha | ✅ | apple-certs repo 의 git HEAD SHA. \A[0-9a-f]{40}\z |
X-Tarball-Sha256 | ✅ | body 의 SHA-256 hex (서버가 재계산 후 비교) |
X-Mirror-Signature | ✅ | sha256=<HMAC-SHA256(hmac_secret, body)> (서버가 재계산 후 timing-safe 비교) |
X-Uploaded-By | 추적용 자유 라벨 (e.g. fastlane:<user>) |
응답 (200)
{
"commit_sha": "268112ce4ed3dec5e04cdf7e517cb72e04772b45",
"sha256": "53c9b81ee0816f70c37f8ea9b790a5f8d4e6c7795f119f24820541de84bf7319",
"byte_size": 60781,
"uploaded_at": "2026-05-16T23:16:43.855Z"
}에러
| HTTP | 의미 | 해결 |
|---|---|---|
| 401 | token 없음 / 잘못됨 | UserMirrorCredential 재발급 |
| 403 | WAF 차단 (default UA) | User-Agent 명시 |
| 411 | Content-Length 헤더 누락 | 헤더 추가 |
| 413 | body 가 50 MB 초과 | apple-certs repo 정리 / 분할 (현재 미지원) |
| 422 | X-Commit-Sha 가 40 hex 형식 아님 | SHA 검증 |
| 422 | X-Tarball-Sha256 가 body 와 불일치 | 전송 중 손상, 재시도 |
| 422 | X-Mirror-Signature HMAC 검증 실패 | hmac_secret 잘못 / body 변조 |
GET /api/cert_mirror
내 모든 blob 목록 (최신 순). 메타데이터만 반환 — 본문 다운로드 X.
요청
GET /api/cert_mirror HTTP/1.1
Authorization: McpKey <token>
User-Agent: ainote-cli/1.0응답 (200)
{
"blobs": [
{
"commit_sha": "268112ce4ed3dec5e04cdf7e517cb72e04772b45",
"sha256": "53c9b81e…",
"byte_size": 60781,
"uploaded_at": "2026-05-16T23:16:43.855Z",
"uploaded_by": "fastlane:seunghan"
}
]
}빈 상태:
{ "blobs": [] }GET /api/cert_mirror/latest
가장 최근 업로드된 blob 의 메타데이터. 폴링 / health check 용.
응답 (200)
{
"commit_sha": "268112ce…",
"sha256": "53c9b81e…",
"byte_size": 60781,
"uploaded_at": "2026-05-16T23:16:43.855Z",
"download_url": "/api/cert_mirror/268112ce4ed3dec5e04cdf7e517cb72e04772b45/download"
}blob 없으면 404:
{ "error": "no blobs yet" }GET /api/cert_mirror/:sha/download
특정 commit_sha 의 tarball 본문 다운로드.
요청
curl -fsSL \
-H "User-Agent: ainote-cli/1.0" \
-H "Authorization: McpKey $TOKEN" \
-o apple-certs.tgz \
https://api.ainote.dev/api/cert_mirror/268112ce4ed3dec5e04cdf7e517cb72e04772b45/download응답
Content-Type: application/octet-stream, body = tarball 바이너리. Content-Length + X-Tarball-Sha256 헤더 함께 반환 (클라이언트에서 다운로드 후 재검증 권장).