인증과 계정 토큰
관리 API 인증 — Sayren 계정 토큰, X-Store-Id, 스코프, 폐기, 구매자 위임
관리 API는 Sayren 계정(accounts.sayren.app)이 발급한 토큰으로만 부릅니다. 토큰은 상점이 아니라 계정에 발급되므로, 토큰 하나로
소속된 여러 상점을 다루고 부를 상점은 요청마다 X-Store-Id 헤더로 고릅니다. 권한은 그 상점에서의 역할과 토큰에 허락한 권한
중 좁은 쪽입니다.
| 종류 | 받는 곳 | 수명 | 쓰는 곳 |
|---|---|---|---|
| 로그인 토큰 | 로그인과 권한 허용 뒤(상점 플랫폼, npx sayren login, 원격 MCP 연결, 연동 앱) | 액세스 15분, 갱신 토큰 30일(쓸 때마다 바뀜, 최대 90일) | 상점 플랫폼·CLI·원격 MCP·연동 앱 |
| 액세스 토큰 | Sayren 계정 › 액세스 토큰에서 직접 만듭니다 | 기본 90일, 최대 365일 | 스크립트·CI·서버 연동·로컬 MCP |
두 토큰 모두 서명된 JWT입니다. 토큰의 내용을 읽어 동작을 정하지 말고 그대로 Authorization: Bearer에 실으십시오.
상점 API 토큰(sy_pat_…), storeToken, 상점 플랫폼의 개발자 › 자격 증명 › API 토큰·앱, 관리 API의 /v1/oauth2/* 인증 경로는
없어졌습니다. 옛 토큰은 401 TOKEN_TYPE_RETIRED, 옛 경로는 410 TOKEN_TYPE_RETIRED입니다. 옮기는 순서는
옛 토큰에서 옮기기에 있습니다.
호출하기
curl https://api.sayren.app/v1/products \
-H "Authorization: Bearer 계정_토큰" \
-H "X-Store-Id: store_abc123"X-Store-Id는 상점 리소스를 부르는 모든 요청에 필요합니다. 상점 id는 상점 플랫폼 주소(/s/{storeId}/…)나 GET /v1/me/stores로 확인합니다.
계정 API(/v1/me, /v1/me/stores)에는 싣지 않아도 됩니다.
curl https://api.sayren.app/v1/me/stores \
-H "Authorization: Bearer 계정_토큰"소속 상점 목록에는 토큰의 상점 범위 안의 상점만 나옵니다. 상점 플랫폼 밖의 토큰은 권한 stores:read(소속 상점 목록)가 있어야 부릅니다.
@sayren/store-sdk는 storeId 옵션을 주면 요청마다 X-Store-Id를 싣습니다.
import { createStoreClient } from "@sayren/store-sdk";
const api = createStoreClient({
baseUrl: "https://api.sayren.app/v1",
accessToken: process.env.SAYREN_ACCESS_TOKEN,
storeId: "store_abc123",
});인증 오류
| 코드 | 상황 |
|---|---|
400 STORE_ID_REQUIRED | 상점 리소스 요청에 X-Store-Id가 없음 |
401 UNAUTHORIZED | 토큰이 없거나 만료·형식 오류 |
401 TOKEN_REVOKED | 폐기된 토큰 |
401 TOKEN_TYPE_RETIRED | 더 이상 받지 않는 옛 토큰(sy_pat_…, storeToken) |
410 TOKEN_TYPE_RETIRED | 없어진 인증 경로(/v1/oauth2/*, /v1/store/api-tokens, /v1/store/api-clients) |
403 STORE_NOT_GRANTED | 토큰을 만들 때(또는 앱에 권한을 허용할 때) 고른 상점 범위 밖의 상점 |
403 NOT_A_MEMBER | 그 상점의 구성원이 아님 |
403 INSUFFICIENT_ROLE | 역할이나 토큰 권한이 모자람 |
403 INSUFFICIENT_SCOPE | 토큰에 필요한 계정 권한(stores:read, member:delegate)이 없음 |
403 TENANT_MISMATCH | 다른 상점의 리소스를 지정함 |
스코프
형식은 {리소스}:{r|rw}이고 rw는 r을 포함합니다. 실제 권한은 역할의 스코프와 토큰에 허락한 스코프의 교집합입니다.
| 리소스 | 접근 수준 | OWNER | ADMIN | STAFF |
|---|---|---|---|---|
product category order claim inquiry review | r rw | rw | rw | rw |
customer promotion | r rw | rw | rw | r |
webhook store member storefront | r rw | rw | rw | — |
analytics audit | r | r | r | — |
settlement | r | r | — | — |
계정 권한은 따로 있습니다. stores:read는 소속 상점 목록, member:delegate는 구매자 위임입니다.
결제 설정, 구매자 로그인 설정, 구성원 초대처럼 일부 작업은 스코프가 있어도 상점 플랫폼에 로그인한 소유자·관리자만 합니다.
액세스 토큰과 연동 앱으로 부르면 403 INSUFFICIENT_ROLE입니다. 각 가이드에 표시되어 있습니다.
액세스 토큰 만들기
Sayren 계정(accounts.sayren.app) › 액세스 토큰 › 토큰 만들기에서 토큰 이름, 권한, 상점 범위, 만료를 고릅니다. 상점 플랫폼의
개발자 › 자격 증명 › 액세스 토큰을 눌러도 이 화면으로 이동합니다.
- 상점 범위: 「선택한 상점」 또는 「모든 상점」입니다. 「모든 상점」은 앞으로 합류할 상점도 포함합니다.
- AI 에이전트용: 로컬 MCP와 원격 MCP에 쓰는 토큰입니다. 이 토큰의 쓰기는 에이전트 쓰기로 기록되고 고위험 작업은 승인을 거칩니다.
- 구매자 위임: 구매자 위임에 쓸 토큰이면 켭니다.
- 보안을 위해 로그인한 지 10분 안에만 만들 수 있습니다. 오래된 로그인이면 다시 로그인하라는 안내가 나옵니다.
- 토큰은 만든 직후 한 번만 보입니다. 사용자당 살아 있는 토큰은 50개까지입니다.
토큰은 사람에게 속합니다. 상점에서 탈퇴하거나 역할이 바뀌면 그 토큰의 권한도 함께 바뀝니다.
로그인 토큰
상점 플랫폼, npx sayren login(스토어프론트 CLI), 원격 MCP는 Sayren 계정 로그인과 권한
허용으로 토큰을 받습니다. 인가 서버는 Sayren 계정이고 흐름은 OAuth 2.1 authorization code + PKCE입니다.
- 관리 API의 인가 서버 정보는
GET https://api.sayren.app/.well-known/oauth-protected-resource(RFC 9728)에 있습니다.authorization_servers가 Sayren 계정입니다. - 브라우저 앱은 store-sdk의
createStoreSession으로 로그인·갱신·로그아웃을 처리합니다(Store SDK).
연결된 앱
로그인 토큰으로 연결한 CLI·원격 MCP·앱은 Sayren 계정 › 연결된 앱에 보입니다. 연결 해제를 누르면 그 앱의 갱신 토큰이 지워지고 이미 받은 로그인 토큰도 곧 거부됩니다. 다시 쓰려면 다시 로그인해 권한을 허용합니다.
폐기와 반영 시간
액세스 토큰 폐기·연결 해제·비밀번호 재설정은 보통 몇 초 안에 API에 반영되고, 늦어도 2분 안에 반영됩니다. 비밀번호를 재설정하면 그 계정의 로그인 토큰과 액세스 토큰이 모두 폐기됩니다.
구매자 위임
자체 회원 시스템을 가진 서버는 로그인한 사용자를 구매자 토큰으로 바꿀 수 있습니다. 역할 스코프 customer:rw와 토큰의
member:delegate(구매자 위임)가 함께 있어야 합니다. 액세스 토큰을 만들 때 구매자 위임을 켜십시오. 계정 액세스 토큰과 Sayren 상점 플랫폼·CLI
로그인만 쓸 수 있고, 다른 앱의 로그인 토큰과 AI 에이전트 요청은 거부됩니다(403 DELEGATION_NOT_ALLOWED).
curl -X POST https://api.sayren.app/v1/customers/delegations \
-H "Authorization: Bearer 계정_토큰" \
-H "X-Store-Id: store_abc123" \
-H "Content-Type: application/json" \
-d '{ "uid": "내_서비스_사용자_id", "email": "buyer@example.com", "name": "홍길동" }'응답 data.accessToken은 스토어프론트 API의 구매자 토큰(30분)입니다. 처음 보는 uid면 구매자를 만듭니다. uid 대신 email만 보내면
이메일로 찾습니다. store-sdk에서는 @sayren/store-sdk/server의 delegateMember를 씁니다(자체 회원 연동).
옛 토큰에서 옮기기
상점 API 토큰(sy_pat_…), storeToken, client_credentials(서버 간 연동) 토큰, token-exchange로 받던 구매자 위임은 모두 끊겼습니다.
함께 쓰는 기간은 없습니다.
| 이전 | 이후 |
|---|---|
| 상점 플랫폼 개발자 › 자격 증명 › API 토큰의 API 토큰 | Sayren 계정 › 액세스 토큰 |
| 상점 플랫폼 개발자 › 자격 증명 › 앱의 서버 간 연동 앱(client_credentials) | 액세스 토큰 |
/v1/oauth2/authorize·/v1/oauth2/token 로그인 | Sayren 계정 로그인(createStoreSession) |
| storeToken 교환(token-exchange) | 로그인 토큰 + X-Store-Id |
token-exchange 구매자 위임(member-uid·member-ref) | POST /v1/customers/delegations |
| 상점 플랫폼에서 폐기하던 앱 | Sayren 계정 › 연결된 앱 |
- Sayren 계정 › 액세스 토큰에서 필요한 권한과 상점 범위로 토큰을 만듭니다.
- 요청의
Authorization을 새 토큰으로 바꾸고X-Store-Id를 싣습니다. - SDK·MCP·CLI를 올립니다.
@sayren/store-sdk0.27.0,@sayren/mcp0.19.0,sayren0.3.0부터 계정 토큰만 씁니다.