대시보드 인증
대시보드 API는 Posmit 대시보드(콘솔)가 사용하는 API 계열로, Authorization: Bearer 헤더에 JWT 액세스 토큰을 담아 인증합니다.
알림 발송 API가 사용하는 API 키 + HMAC 서명 인증(인증 참고)과는 완전히 별개의 인증 체계이며, API 키나 서명 헤더는 대시보드 API에서 사용하지 않습니다.
워크스페이스·공급자·템플릿·발송 큐·레이트리밋 정책 등 대시보드 API 문서의 모든 엔드포인트가 이 페이지의 인증을 공통으로 사용합니다.
대시보드 API의 성공 응답은 컨트롤러가 반환한 JSON을 그대로 내려줍니다.
알림 API와 달리 data / meta 봉투(envelope)로 감싸지 않습니다.
에러는 알림 API와 동일하게 RFC 7807 application/problem+json 형식입니다.
토큰 종류와 수명
로그인하면 액세스 토큰과 리프레시 토큰 한 쌍이 발급됩니다.
| 토큰 | 기본 수명 | 용도 |
|---|---|---|
| 액세스 토큰 | 900초(15분) | Authorization: Bearer 헤더로 API 호출에 사용합니다. |
| 리프레시 토큰 | 1,209,600초(14일) | 액세스 토큰 재발급에 사용합니다. 1회용입니다. |
- 수명은 서버 설정으로 조정될 수 있으며, 위 값은 기본값입니다.
- 리프레시 토큰은 사용할 때마다 회전(rotation) 됩니다. 갱신에 사용한 토큰의 세션은 즉시 폐기되고 새 토큰 쌍이 발급되므로, 같은 리프레시 토큰을 두 번 사용하면 401이 반환됩니다.
workspaceBound — 워크스페이스 바인딩
액세스 토큰에는 workspaceBound 클레임이 있습니다.
- 바인딩 토큰(
workspaceBound: true)은 특정 워크스페이스와 역할(role)에 묶인 토큰입니다. 역할 검사가 걸린 리소스 API(공급자, 템플릿, 정책 등)는 바인딩 토큰을 요구하며, 바인딩되지 않은 토큰으로 호출하면403 Forbidden(Workspace selection required)이 반환됩니다. - 비바인딩 토큰(
workspaceBound: false)은 소속 워크스페이스가 하나도 없을 때 발급됩니다. 워크스페이스 목록 조회·생성 등 로그인만 요구하는 API에는 사용할 수 있습니다.
바인딩 토큰의 역할은 요청마다 서버가 멤버십 DB와 대조합니다. 멤버십이 제거된 사용자는 토큰이 아직 유효하더라도 401이 반환됩니다.
토큰 획득 흐름
로그인
Firebase ID 토큰으로 POST /v1/auth/login을 호출해 토큰 쌍을 받습니다.
소속 워크스페이스가 있으면 이 단계에서 바로 바인딩 토큰이 발급됩니다.
워크스페이스 선택
다른 워크스페이스로 전환하거나, 바인딩되지 않은 경우 POST /v1/auth/workspaces/:workspaceId/select로 해당 워크스페이스에 바인딩된 토큰 쌍을 새로 받습니다.
리소스 API 호출
바인딩된 액세스 토큰을 Authorization: Bearer 헤더에 담아 리소스 API를 호출합니다.
액세스 토큰이 만료되면 POST /v1/auth/refresh로 갱신합니다.
로그인
Firebase ID 토큰을 검증하고 대시보드용 액세스/리프레시 토큰을 발급합니다. (무인증)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
firebaseIdToken | string | 필수 | Firebase Authentication이 발급한 ID 토큰입니다. |
workspaceId | UUID | 선택 | 바인딩할 워크스페이스를 지정합니다. 생략하거나 멤버십이 없으면 가장 먼저 가입한 워크스페이스로 바인딩됩니다. |
소속 워크스페이스가 하나도 없으면 workspaceBound: false, workspaceId: null, role: null인 토큰이 발급됩니다.
curl -X POST https://api.posmit.io/v1/auth/login \
-H "Content-Type: application/json" \
-d '{ "firebaseIdToken": "eyJhbGciOiJSUzI1NiIs..." }'{
"status": "authenticated",
"tokens": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"workspaceId": "3f6a...",
"role": "owner",
"userId": "9b1c...",
"workspaceBound": true
}
}| 상태 | 코드 | 의미 |
|---|---|---|
| 400 | NOTI-40000 | 요청 본문 검증 실패(필드 누락, 허용되지 않은 필드 등) |
| 401 | NOTI-40100 | Firebase ID 토큰 검증 실패 |
토큰 갱신
리프레시 토큰으로 새 토큰 쌍을 발급합니다. (무인증 — 리프레시 토큰을 본문으로 전달)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
refreshToken | string | 필수 | 발급받은 리프레시 토큰입니다. |
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"workspaceId": "3f6a...",
"role": "owner",
"userId": "9b1c...",
"workspaceBound": true
}| 상태 | 코드 | 의미 |
|---|---|---|
| 401 | NOTI-40100 | 리프레시 토큰이 유효하지 않음(서명 오류, 만료, 이미 사용됨(회전), 세션 폐기, 워크스페이스 멤버십 없음) |
갱신에 성공하면 이전 리프레시 토큰은 즉시 무효화됩니다. 응답의 새 토큰 쌍으로 반드시 교체해 보관하세요.
워크스페이스 선택
지정한 워크스페이스에 바인딩된 토큰 쌍을 새로 발급합니다. (Bearer — 비바인딩 토큰도 사용 가능)
요청 본문은 없으며, 응답 형식은 토큰 갱신과 같고 workspaceBound는 항상 true입니다.
| 상태 | 코드 | 의미 |
|---|---|---|
| 400 | NOTI-40000 | workspaceId가 UUID 형식이 아님 |
| 401 | NOTI-40100 | 액세스 토큰이 유효하지 않거나, 해당 워크스페이스의 멤버가 아님 |
내 정보 조회
현재 토큰의 인증 컨텍스트를 조회합니다. (Bearer)
바인딩되지 않은 토큰이면 workspaceId와 role은 null입니다.
{
"userId": "9b1c...",
"workspaceId": "3f6a...",
"role": "owner",
"sessionId": "77e2...",
"workspaceBound": true
}로그아웃
발급받은 세션(리프레시 토큰)을 폐기합니다.
현재 세션 하나만 끊는 logout과 사용자의 모든 세션을 한 번에 끊는 logout-all 두 가지가 있습니다.
리프레시 토큰 하나에 연결된 현재 세션만 폐기합니다. (무인증 — 리프레시 토큰을 본문으로 전달) 액세스 토큰이 아니라 리프레시 토큰을 보내며, 폐기된 세션의 리프레시 토큰은 이후 갱신에 사용할 수 없습니다.
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
refreshToken | string | 필수 | 폐기할 세션의 리프레시 토큰입니다. |
{ "status": "logged_out" }토큰이 유효하지 않거나 이미 폐기된 세션이어도 정보 노출을 피하기 위해 항상 200 { "status": "logged_out" }를 반환하며, 같은 토큰으로 다시 호출해도 동일하게 동작하는 멱등 엔드포인트입니다.
refreshToken 필드가 없거나 문자열이 아니면 400 NOTI-40000으로 거부됩니다.
액세스 토큰이 가리키는 사용자의 모든 활성 세션을 한 번에 폐기합니다. (Bearer) 모든 기기·브라우저에서 로그아웃되며, 요청 본문은 없고 대상 사용자는 액세스 토큰에서 도출됩니다.
{ "status": "logged_out" }이미 활성 세션이 없어도 200을 반환하는 멱등 엔드포인트이며, 액세스 토큰이 없거나 유효하지 않으면 401 NOTI-40100이 반환됩니다.
logout은 리프레시 토큰으로 그 세션 하나만, logout-all은 액세스 토큰으로 그 사용자의 모든 세션을 끊습니다.
로그아웃 뒤 폐기된 세션의 리프레시 토큰으로 POST /v1/auth/refresh를 호출하면 401 NOTI-40100이 반환됩니다.
역할과 RBAC
워크스페이스 멤버는 네 가지 역할 중 하나를 가지며, 바인딩 토큰에 역할이 포함됩니다.
각 리소스 엔드포인트는 허용 역할 목록을 선언하고, 토큰의 역할이 목록에 없으면 403 Forbidden이 반환됩니다.
| 역할 | 권한 요약 |
|---|---|
owner | 모든 작업을 수행할 수 있습니다. 워크스페이스 삭제는 owner만 가능합니다. |
admin | 워크스페이스 수정, 정책·설정 변경 등 owner와 거의 동일한 관리 작업을 수행합니다. |
operator | 발송·재시도·취소 같은 운영성 쓰기 작업이 가능합니다. 설정 변경은 불가합니다. |
viewer | 조회 전용입니다. |
RBAC 검사 순서는 다음과 같습니다.
- Bearer 토큰 검증에 실패하면
401(NOTI-40100)이 반환됩니다. - 역할 검사가 걸린 엔드포인트를 비바인딩 토큰으로 호출하면
403(NOTI-40300, Workspace selection required)이 반환됩니다. - 바인딩 토큰이라도 역할이 허용 목록에 없으면
403(NOTI-40300, Insufficient role permissions)이 반환됩니다.
각 엔드포인트가 요구하는 역할은 해당 문서의 (역할: ...) 표기를 참고하세요.