endpoints
관련 문서
- Auth 도메인 엔드포인트: /domains/common/core-domains/auth/endpoints
IAM API 엔드포인트
목차
- 관련 문서
- 1. 엔드포인트 접근 권한 매트릭스
- 2. 서비스 간 인증 API
- 3. Service Account 관리 API
- 4. 권한 관리 API
- 5. 역할 관리 API
- 6. 사용자 권한 관리 API
- 7. 정책 관리 API
- 8. 오류 코드
- 9. 변경 이력
관련 문서
1. 엔드포인트 접근 권한 매트릭스
| 엔드포인트 | System Admin | IAM Admin | Service Account | Regular User | 비고 |
|---|---|---|---|---|---|
| POST /v1/iam/auth/token | ✓ | ✘ | ✓ (자신만) | ✘ | Service Account 토큰 발급 |
| POST /v1/iam/auth/verify | ✓ | ✓ | ✓ | ✓ | 토큰 검증 |
| POST /v1/iam/auth/refresh | ✓ | ✘ | ✓ (자신만) | ✘ | 토큰 갱신 |
| POST /v1/iam/auth/revoke | ✓ | ✓ | ✓ (자신만) | ✘ | 토큰 무효화 |
| POST /v1/iam/service-accounts | ✓ | ✓ | ✘ | ✘ | |
| GET /v1/iam/service-accounts | ✓ | ✓ | ✘ | ✘ | |
GET /v1/iam/service-accounts/{id} | ✓ | ✓ | ✓ (자신만) | ✘ | |
PATCH /v1/iam/service-accounts/{id} | ✓ | ✓ | ✓ (자신만) | ✘ | |
DELETE /v1/iam/service-accounts/{id} | ✓ | ✓ | ✘ | ✘ | |
POST /v1/iam/service-accounts/{id}/api-key | ✓ | ✓ | ✘ | ✘ | API 키 재생성 |
| POST /v1/iam/permissions | ✓ | ✓ | ✘ | ✘ | |
| GET /v1/iam/permissions | ✓ | ✓ | ✓ | ✓ | |
GET /v1/iam/permissions/{id} | ✓ | ✓ | ✓ | ✓ | |
PATCH /v1/iam/permissions/{id} | ✓ | ✓ | ✘ | ✘ | |
DELETE /v1/iam/permissions/{id} | ✓ | ✘ | ✘ | ✘ | System Admin만 삭제 가능 |
| POST /v1/iam/permissions/verify | ✓ | ✓ | ✓ | ✓ | 권한 검증 |
| POST /v1/iam/roles | ✓ | ✓ | ✘ | ✘ | |
| GET /v1/iam/roles | ✓ | ✓ | ✓ | ✓ | |
GET /v1/iam/roles/{id} | ✓ | ✓ | ✓ | ✓ | |
PATCH /v1/iam/roles/{id} | ✓ | ✓ | ✘ | ✘ | |
DELETE /v1/iam/roles/{id} | ✓ | ✘ | ✘ | ✘ | System Admin만 삭제 가능 |
POST /v1/iam/roles/{id}/permissions | ✓ | ✓ | ✘ | ✘ | |
DELETE /v1/iam/roles/{id}/permissions/{permissionId} | ✓ | ✓ | ✘ | ✘ | |
GET /v1/iam/users/{userId}/permissions | ✓ | ✓ | ✓ (제한적) | ✓ (자신만) | |
POST /v1/iam/users/{userId}/roles | ✓ | ✓ | ✘ | ✘ | |
DELETE /v1/iam/users/{userId}/roles/{roleId} | ✓ | ✓ | ✘ | ✘ | |
| POST /v1/iam/policies | ✓ | ✓ | ✘ | ✘ | |
| GET /v1/iam/policies | ✓ | ✓ | ✓ | ✘ | |
GET /v1/iam/policies/{id} | ✓ | ✓ | ✓ | ✘ | |
PATCH /v1/iam/policies/{id} | ✓ | ✓ | ✘ | ✘ | |
DELETE /v1/iam/policies/{id} | ✓ | ✘ | ✘ | ✘ | System Admin만 삭제 가능 |
| POST /v1/iam/policies/evaluate | ✓ | ✓ | ✓ | ✓ | 정책 평가 |
참고:
- ✓: 접근 가능
- ✘: 접근 불가
- (자신만): 자신의 데이터에만 접근 가능
- (제한적): 특정 필드만 조회/수정 가능
2. 서비스 간 인증 API
인증 방식 개요
Service Account 인증은 Google Service Account와 동일한 패턴을 사용합니다:
- 장기 자격증명 (API Key): Service Account 생성 시 발급되는 장기 보관용 인증 키
- 단기 접근 토큰 (JWT Token): API Key로 발급받는 단기 유효 토큰 (실제 API 호출용)
Service Account 인증 플로우:
API Key → JWT Token 발급 → Bearer Token으로 API 호출 → 토큰 만료 시 재발급
주요 특징:
- 리프레시 토큰을 사용하지 않음 (일반 사용자와 다름)
- 토큰 갱신 기능을 지원하지 않음
- API Key는 장기 자격증명, JWT Token은 단기 접근 토큰
- 토큰 만료 시 API Key로 새 토큰 발급 (갱신 불가)
권장사항:
- 토큰 만료 전에 미리 새 토큰을 발급받아 무중단 서비스 구현
2.1 Service Account 토큰 발급
- HTTP 메서드: POST
- 경로: /v1/iam/auth/token
- Headers:
- Content-Type: application/json
- 설명: Service Account가 **장기 자격증명(API Key)**을 사용하여 **단기 접근 토큰(JWT)**을 발급받습니다.
요청 (Request)
{
"serviceId": "sa_abc123",
"apiKey": "sk_live_abc123def456...", // 장기 자격증명
"audience": "dta-wide-api", // 선택적: 대상 서비스
"expiresIn": 3600 // 선택적: 토큰 유효 기간(초), 기본값: 1시간
}
응답 (Response)
- 성공 응답 (200 OK)
{
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", // 단기 접근 토큰
"tokenType": "Bearer",
"expiresIn": 3600,
"issuedAt": 1711011600000,
"audience": "dta-wide-api"
// 참고: refreshToken 필드는 없습니다 (Service Account는 리프레시 토큰을 사용하지 않음)
}
- 오류 응답 (401 Unauthorized)
{
"code": 5001,
"message": "INVALID_SERVICE_CREDENTIALS",
"detail": "Service ID 또는 API 키가 유효하지 않습니다."
}
- 오류 응답 (403 Forbidden)
{
"code": 5002,
"message": "SERVICE_ACCOUNT_INACTIVE",
"detail": "비활성화된 Service Account입니다."
}
2.2 Service Account 토큰 검증
- HTTP 메서드: POST
- 경로: /v1/iam/auth/verify
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}(선택적)
요청 (Request)
{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", // 검증할 토큰
"requiredPermissions": ["user:read", "user:write"], // 선택적: 필요한 권한 목록
"resource": "user:123" // 선택적: 리소스 컨텍스트
}
응답 (Response)
- 성공 응답 (200 OK)
{
"valid": true,
"serviceId": "sa_abc123",
"permissions": ["user:read", "user:write", "system:health"],
"roles": ["service.backend", "user.reader"],
"expiresAt": 1711015200000,
"audience": "dta-wide-api"
}
- 오류 응답 (401 Unauthorized)
{
"code": 5003,
"message": "INVALID_TOKEN",
"detail": "토큰이 유효하지 않거나 만료되었습니다."
}
- 오류 응답 (403 Forbidden)
{
"code": 5004,
"message": "INSUFFICIENT_PERMISSIONS",
"detail": "요청한 작업에 필요한 권한이 없습니다."
}
2.3 Service Account 토큰 갱신 (지원되지 않음)
- HTTP 메서드: POST
- 경로: /v1/iam/auth/refresh
- 중요: Service Account는 토큰 갱신을 지원하지 않습니다.
Service Account 토큰 관리 방식
Service Account는 일반 사용자와 다른 토큰 관리 방식을 사용합니다:
- 일반 사용자: Access Token + Refresh Token 방식 (토큰 갱신 지원)
- Service Account: API Key → JWT Token 방식 (토큰 갱신 미지원)
토큰 만료 시 대응 방법
Service Account 토큰이 만료된 경우:
- API Key로 새 토큰 발급:
/v1/iam/auth/token엔드포인트 사용 - 토큰 만료 전 미리 재발급: 애플리케이션에서 토큰 만료 시간을 추적하여 사전에 재발급
현재 엔드포인트 호출 시 응답
- 오류 응답 (400 Bad Request)
{
"statusCode": 400,
"message": "Service accounts do not support token refresh. Use API key to issue a new token.",
"error": "Bad Request"
}
권장사항: Service Account를 사용하는 애플리케이션은 토큰 만료 전에 API Key를 사용하여 새로운 토큰을 발급받도록 구현하세요.
2.4 Service Account 토큰 무효화
- HTTP 메서드: POST
- 경로: /v1/iam/auth/revoke
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
요청 (Request)
{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", // 선택적: 특정 토큰, 없으면 현재 토큰
"revokeAll": false // 선택적: 해당 Service Account의 모든 토큰 무효화
}
응답 (Response)
- 성공 응답 (200 OK)
{
"message": "토큰이 성공적으로 무효화되었습니다.",
"revokedAt": 1711015800000,
"tokensRevoked": 1
}
3. Service Account 관리 API
Service Account 개념
- Service Account: 서비스 간 통신을 위한 특별한 계정 (Google Service Account와 유사)
- API Key: Service Account의 장기 자격증명 (Google의 Private Key와 동일한 역할)
- JWT Token: API Key로 발급받는 단기 접근 토큰 (실제 API 호출용)
- 중요: Service Account는 리프레시 토큰을 사용하지 않습니다 (일반 사용자 인증과 다름)
3.1 Service Account 생성
- HTTP 메서드: POST
- 경로: /v1/iam/service-accounts
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
- 설명: 새로운 Service Account와 초기 **장기 자격증명(API Key)**을 생성합니다.
요청 (Request)
{
"accountId": "backend-service-a", // 이메일 로컬 부분 (영문자, 숫자, 하이픈만 허용)
"displayName": "Backend Service A", // 선택적: 사용자 친화적 표시 이름
"description": "Service account for internal backend communication",
"roles": ["service.backend", "user.reader"], // 선택적: 초기 역할 할당
"expiresAt": 1743465600000 // 선택적: 계정 만료일
}
참고:
accountId는 이메일 주소의 로컬 부분으로 사용됩니다. (예:backend-service-a@project-dev.iam.serviceaccount.com)accountId는 영문자(a-z), 숫자(0-9), 하이픈(-)만 허용하며, 6-30자 길이여야 합니다.displayName은 UI에서 표시되는 사용자 친화적 이름입니다.
응답 (Response)
- 성공 응답 (201 Created)
{
"id": "sa_abc123",
"accountId": "backend-service-a",
"email": "backend-service-a@project-dev.iam.serviceaccount.com", // 생성된 이메일 주소
"displayName": "Backend Service A",
"description": "Service account for internal backend communication",
"status": "ACTIVE",
"apiKey": "sk_live_abc123def456...", // 장기 자격증명 (최초 생성 시에만 반환)
"roles": ["service.backend", "user.reader"],
"createdAt": 1711011600000,
"updatedAt": 1711011600000,
"expiresAt": 1743465600000
}
- 오류 응답 (400 Bad Request)
{
"code": 5011,
"message": "INVALID_SERVICE_ACCOUNT_DATA",
"detail": "Service Account 데이터가 유효하지 않습니다."
}
- 오류 응답 (409 Conflict)
{
"code": 5012,
"message": "SERVICE_ACCOUNT_ID_EXISTS",
"detail": "동일한 Account ID의 Service Account가 이미 존재합니다."
}
3.2 Service Account 조회
- HTTP 메서드: GET
- 경로: /v1/iam/service-accounts/
{id} - Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "sa_abc123",
"accountId": "backend-service-a",
"email": "backend-service-a@project-dev.iam.serviceaccount.com",
"displayName": "Backend Service A",
"description": "Service account for internal backend communication",
"status": "ACTIVE",
"roles": ["service.backend", "user.reader"],
"permissions": ["user:read", "user:write", "system:health"],
"createdAt": 1711011600000,
"updatedAt": 1711015200000,
"expiresAt": 1743465600000,
"lastUsedAt": 1711014800000
// API 키는 보안상 반환하지 않음
}
- 오류 응답 (404 Not Found)
{
"code": 5013,
"message": "SERVICE_ACCOUNT_NOT_FOUND",
"detail": "Service Account를 찾을 수 없습니다."
}
3.3 Service Account 수정
- HTTP 메서드: PATCH
- 경로: /v1/iam/service-accounts/
{id} - Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
요청 (Request)
{
"displayName": "Updated Backend Service A",
"description": "Updated description",
"expiresAt": 1775001600000
}
참고:
accountId와
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "sa_abc123",
"accountId": "backend-service-a",
"email": "backend-service-a@project-dev.iam.serviceaccount.com",
"displayName": "Updated Backend Service A",
"description": "Updated description",
"status": "ACTIVE",
"roles": ["service.backend", "user.reader"],
"createdAt": 1711011600000,
"updatedAt": 1711016000000,
"expiresAt": 1775001600000
}
3.4 Service Account 비활성화
- HTTP 메서드: DELETE
- 경로: /v1/iam/service-accounts/
{id} - Headers:
- Authorization: Bearer
{adminToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"message": "Service Account가 성공적으로 비활성화되었습니다.",
"id": "sa_abc123",
"status": "INACTIVE",
"deactivatedAt": 1711016400000
}
3.5 API 키 재생성
- HTTP 메서드: POST
- 경로: /v1/iam/service-accounts/
{id}/api-key - Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
- 설명: 보안 로테이션을 위해 Service Account의 **장기 자격증명(API Key)**을 재생성합니다. (Google Service Account의 Private Key 재생성과 동일)
요청 (Request)
{
"reason": "Security rotation"
}
응답 (Response)
- 성공 응답 (200 OK)
{
"apiKey": "sk_live_new123def456...", // 새로 생성된 장기 자격증명
"regeneratedAt": 1711016800000,
"message": "API 키가 성공적으로 재생성되었습니다. 이전 키는 즉시 무효화됩니다."
}
4. 권한 관리 API
4.1 권한 생성
- HTTP 메서드: POST
- 경로: /v1/iam/permissions
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
요청 (Request)
{
"name": "user:delete",
"description": "사용자 삭제 권한",
"resource": "user",
"action": "delete",
"metadata": {
"category": "user_management",
"severity": "high"
}
}
응답 (Response)
- 성공 응답 (201 Created)
{
"id": "perm_123",
"name": "user:delete",
"description": "사용자 삭제 권한",
"resource": "user",
"action": "delete",
"metadata": {
"category": "user_management",
"severity": "high"
},
"createdAt": 1711017200000,
"updatedAt": 1711017200000
}
4.2 권한 조회
- HTTP 메서드: GET
- 경로: /v1/iam/permissions/
{id} - Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "perm_123",
"name": "user:delete",
"description": "사용자 삭제 권한",
"resource": "user",
"action": "delete",
"metadata": {
"category": "user_management",
"severity": "high"
},
"createdAt": 1711017200000,
"updatedAt": 1711017200000
}
4.3 권한 수정
- HTTP 메서드: PATCH
- 경로: /v1/iam/permissions/
{id} - Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
요청 (Request)
{
"description": "사용자 계정 삭제 권한 (업데이트됨)",
"metadata": {
"category": "user_management",
"severity": "critical"
}
}
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "perm_123",
"name": "user:delete",
"description": "사용자 계정 삭제 권한 (업데이트됨)",
"resource": "user",
"action": "delete",
"metadata": {
"category": "user_management",
"severity": "critical"
},
"createdAt": 1711017200000,
"updatedAt": 1711017800000
}
4.4 권한 삭제
- HTTP 메서드: DELETE
- 경로: /v1/iam/permissions/
{id} - Headers:
- Authorization: Bearer
{systemAdminToken}
- Authorization: Bearer
- 비고: System Admin만 권한 삭제 가능
응답 (Response)
- 성공 응답 (200 OK)
{
"message": "권한이 성공적으로 삭제되었습니다.",
"id": "perm_123",
"deletedAt": 1711018200000
}
4.5 권한 검증
- HTTP 메서드: POST
- 경로: /v1/iam/permissions/verify
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
요청 (Request)
{
"userId": "user_123", // 선택적: 특정 사용자, 없으면 현재 인증된 사용자
"permissions": ["user:read", "user:write"],
"resource": "user:456", // 선택적: 리소스 컨텍스트
"context": { // 선택적: 추가 컨텍스트
"ip": "192.168.1.100",
"userAgent": "Mozilla/5.0..."
}
}
응답 (Response)
- 성공 응답 (200 OK)
{
"userId": "user_123",
"results": [
{
"permission": "user:read",
"granted": true,
"reason": "User has role 'user.reader'"
},
{
"permission": "user:write",
"granted": false,
"reason": "User lacks required role"
}
],
"evaluatedAt": 1711018600000
}
5. 역할 관리 API
5.1 역할 생성
- HTTP 메서드: POST
- 경로: /v1/iam/roles
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
요청 (Request)
{
"name": "user.manager",
"description": "사용자 관리자 역할",
"permissions": ["user:read", "user:write", "user:list"],
"metadata": {
"department": "operations",
"level": "manager"
}
}
응답 (Response)
- 성공 응답 (201 Created)
{
"id": "role_456",
"name": "user.manager",
"description": "사용자 관리자 역할",
"permissions": ["user:read", "user:write", "user:list"],
"metadata": {
"department": "operations",
"level": "manager"
},
"createdAt": 1711019000000,
"updatedAt": 1711019000000
}
5.2 역할 조회
- HTTP 메서드: GET
- 경로: /v1/iam/roles/
{id} - Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "role_456",
"name": "user.manager",
"description": "사용자 관리자 역할",
"permissions": ["user:read", "user:write", "user:list"],
"metadata": {
"department": "operations",
"level": "manager"
},
"createdAt": 1711019000000,
"updatedAt": 1711019000000
}
5.3 역할 수정
- HTTP 메서드: PATCH
- 경로: /v1/iam/roles/
{id} - Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
요청 (Request)
{
"description": "사용자 관리자 역할 (업데이트됨)",
"metadata": {
"department": "operations",
"level": "senior_manager"
}
}
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "role_456",
"name": "user.manager",
"description": "사용자 관리자 역할 (업데이트됨)",
"permissions": ["user:read", "user:write", "user:list"],
"metadata": {
"department": "operations",
"level": "senior_manager"
},
"createdAt": 1711019000000,
"updatedAt": 1711019600000
}
5.4 역할 삭제
- HTTP 메서드: DELETE
- 경로: /v1/iam/roles/
{id} - Headers:
- Authorization: Bearer
{systemAdminToken}
- Authorization: Bearer
- 비고: System Admin만 역할 삭제 가능
응답 (Response)
- 성공 응답 (200 OK)
{
"message": "역할이 성공적으로 삭제되었습니다.",
"id": "role_456",
"deletedAt": 1711020000000
}
5.5 역할에 권한 할당
- HTTP 메서드: POST
- 경로: /v1/iam/roles/
{id}/permissions - Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
요청 (Request)
{
"permissions": ["user:delete", "user:suspend"]
}
응답 (Response)
- 성공 응답 (200 OK)
{
"roleId": "role_456",
"addedPermissions": ["user:delete", "user:suspend"],
"totalPermissions": ["user:read", "user:write", "user:list", "user:delete", "user:suspend"],
"updatedAt": 1711020400000
}
5.6 역할에서 권한 해제
- HTTP 메서드: DELETE
- 경로: /v1/iam/roles/
{id}/permissions/{permissionId} - Headers:
- Authorization: Bearer
{adminToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"roleId": "role_456",
"removedPermission": "user:delete",
"remainingPermissions": ["user:read", "user:write", "user:list", "user:suspend"],
"updatedAt": 1711020800000
}
6. 사용자 권한 관리 API
6.1 사용자 권한 조회
- HTTP 메서드: GET
- 경로: /v1/iam/users/
{userId}/permissions - Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"userId": "user_123",
"identityLevel": "registered",
"roles": [
{
"id": "role_456",
"name": "user.manager",
"assignedAt": 1711021200000
}
],
"permissions": [
{
"name": "user:read",
"source": "role:user.manager"
},
{
"name": "user:write",
"source": "role:user.manager"
}
],
"effectivePermissions": ["user:read", "user:write", "user:list"],
"identityLevelPolicy": {
"requiresIdentityLevel": "registered",
"decision": "allow"
},
"evaluatedAt": 1711021600000,
"cache": {
"status": "WARM",
"ttl": 45
}
}
6.2 사용자에게 역할 할당
- HTTP 메서드: POST
- 경로: /v1/iam/users/
{userId}/roles - Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
요청 (Request)
{
"roles": ["user.manager", "content.reviewer"],
"reason": "Promoted to manager position"
}
응답 (Response)
- 성공 응답 (200 OK)
{
"userId": "user_123",
"addedRoles": [
{
"id": "role_456",
"name": "user.manager",
"assignedAt": 1711022000000
},
{
"id": "role_789",
"name": "content.reviewer",
"assignedAt": 1711022000000
}
],
"totalRoles": ["user.manager", "content.reviewer"],
"updatedAt": 1711022000000
}
6.3 사용자에서 역할 해제
- HTTP 메서드: DELETE
- 경로: /v1/iam/users/
{userId}/roles/{roleId} - Headers:
- Authorization: Bearer
{adminToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"userId": "user_123",
"removedRole": {
"id": "role_789",
"name": "content.reviewer",
"removedAt": 1711022400000
},
"remainingRoles": ["user.manager"],
"updatedAt": 1711022400000
}
6.4 identityLevel 기반 인가 평가
- HTTP 메서드: POST
- 경로: /v1/iam/access/evaluate
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
- 설명: 플랜/그룹 권한과 identityLevel 정책을 모두 고려하여 특정 리소스에 대한 접근을 평가합니다. 게스트 토큰의 제한을 검증할 때 사용합니다.
요청 (Request)
{
"userId": "user_guest_01",
"resource": "sleep:program:write",
"identityLevel": "guest",
"context": {
"planId": "plan.guest.default",
"groupIds": ["patients.guest.de"],
"operation": "WRITE"
}
}
응답 (Response) - 200 OK
{
"allowed": false,
"decision": "DENY",
"reason": "IDENTITY_LEVEL_INSUFFICIENT",
"identityLevel": "guest",
"requiredIdentityLevel": "registered",
"effectivePermissions": ["sleep:program:read"],
"evaluatedAt": 1714600500000
}
7. 정책 관리 API
7.1 정책 생성
- HTTP 메서드: POST
- 경로: /v1/iam/policies
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
요청 (Request)
{
"name": "business_hours_access",
"description": "업무 시간 중에만 접근 허용",
"conditions": {
"time": {
"start": "09:00",
"end": "18:00",
"timezone": "Asia/Seoul"
},
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"]
},
"effect": "ALLOW",
"priority": 100,
"resources": ["user:*", "content:*"]
}
응답 (Response)
- 성공 응답 (201 Created)
{
"id": "policy_abc",
"name": "business_hours_access",
"description": "업무 시간 중에만 접근 허용",
"conditions": {
"time": {
"start": "09:00",
"end": "18:00",
"timezone": "Asia/Seoul"
},
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"]
},
"effect": "ALLOW",
"priority": 100,
"resources": ["user:*", "content:*"],
"version": 1,
"createdAt": 1711022800000,
"updatedAt": 1711022800000
}
7.2 정책 조회
- HTTP 메서드: GET
- 경로: /v1/iam/policies/
{id} - Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "policy_abc",
"name": "business_hours_access",
"description": "업무 시간 중에만 접근 허용",
"conditions": {
"time": {
"start": "09:00",
"end": "18:00",
"timezone": "Asia/Seoul"
},
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"]
},
"effect": "ALLOW",
"priority": 100,
"resources": ["user:*", "content:*"],
"version": 1,
"createdAt": 1711022800000,
"updatedAt": 1711022800000
}
7.3 정책 수정
- HTTP 메서드: PATCH
- 경로: /v1/iam/policies/
{id} - Headers:
- Content-Type: application/json
- Authorization: Bearer
{adminToken}
요청 (Request)
{
"description": "업무 시간 중에만 접근 허용 (업데이트됨)",
"conditions": {
"time": {
"start": "08:00",
"end": "19:00",
"timezone": "Asia/Seoul"
},
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"]
}
}
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "policy_abc",
"name": "business_hours_access",
"description": "업무 시간 중에만 접근 허용 (업데이트됨)",
"conditions": {
"time": {
"start": "08:00",
"end": "19:00",
"timezone": "Asia/Seoul"
},
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"]
},
"effect": "ALLOW",
"priority": 100,
"resources": ["user:*", "content:*"],
"version": 2,
"createdAt": 1711022800000,
"updatedAt": 1711023200000
}
7.4 정책 삭제
- HTTP 메서드: DELETE
- 경로: /v1/iam/policies/
{id} - Headers:
- Authorization: Bearer
{systemAdminToken}
- Authorization: Bearer
- 비고: System Admin만 정책 삭제 가능
응답 (Response)
- 성공 응답 (200 OK)
{
"message": "정책이 성공적으로 삭제되었습니다.",
"id": "policy_abc",
"deletedAt": 1711023600000
}
7.5 정책 평가
- HTTP 메서드: POST
- 경로: /v1/iam/policies/evaluate
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
요청 (Request)
{
"userId": "user_123", // 선택적: 특정 사용자, 없으면 현재 인증된 사용자
"action": "user:read",
"resource": "user:456",
"context": {
"ip": "192.168.1.100",
"userAgent": "Mozilla/5.0...",
"timestamp": 1711024000000
}
}
응답 (Response)
- 성공 응답 (200 OK)
{
"decision": "ALLOW",
"userId": "user_123",
"action": "user:read",
"resource": "user:456",
"appliedPolicies": [
{
"id": "policy_abc",
"name": "business_hours_access",
"effect": "ALLOW",
"matched": true,
"reason": "Current time is within business hours"
}
],
"evaluatedAt": 1711024000000,
"ttl": 300 // 캐시 TTL (초)
}
8. 오류 코드
IAM 도메인 API에서 사용하는 주요 오류 코드는 다음과 같습니다.
| HTTP 상태 코드 | 오류 코드 (IAM: 5xxx) | 메시지 (Error Class) | 설명 |
|---|---|---|---|
| 500 | (공유) 2000 | SERVER_ERROR | 서버 내부 오류 |
| 401 | (Auth) 2001 | UNAUTHORIZED | 인증이 필요합니다 |
| 403 | (Auth) 2002 | FORBIDDEN | 권한이 없습니다 |
| 403 | (Auth) 2060 | PERMISSION_DENIED | 요청한 작업/리소스에 대한 권한이 없습니다 |
| 401 | 5001 | INVALID_SERVICE_CREDENTIALS | Service ID 또는 API 키가 유효하지 않음 |
| 403 | 5002 | SERVICE_ACCOUNT_INACTIVE | 비활성화된 Service Account |
| 401 | 5003 | INVALID_TOKEN | 토큰이 유효하지 않거나 만료됨 |
| 403 | 5004 | INSUFFICIENT_PERMISSIONS | 요청한 작업에 필요한 권한이 없음 |
| 400 | 5011 | INVALID_SERVICE_ACCOUNT_DATA | Service Account 데이터가 유효하지 않음 |
| 409 | 5012 | SERVICE_ACCOUNT_ID_EXISTS | 동일한 Account ID의 Service Account가 이미 존재 |
| 404 | 5013 | SERVICE_ACCOUNT_NOT_FOUND | Service Account를 찾을 수 없음 |
| 400 | 5021 | INVALID_PERMISSION_DATA | 권한 데이터가 유효하지 않음 |
| 409 | 5022 | PERMISSION_NAME_EXISTS | 동일한 이름의 권한이 이미 존재 |
| 404 | 5023 | PERMISSION_NOT_FOUND | 권한을 찾을 수 없음 |
| 400 | 5031 | INVALID_ROLE_DATA | 역할 데이터가 유효하지 않음 |
| 409 | 5032 | ROLE_NAME_EXISTS | 동일한 이름의 역할이 이미 존재 |
| 404 | 5033 | ROLE_NOT_FOUND | 역할을 찾을 수 없음 |
| 400 | 5041 | INVALID_POLICY_DATA | 정책 데이터가 유효하지 않음 |
| 409 | 5042 | POLICY_NAME_EXISTS | 동일한 이름의 정책이 이미 존재 |
| 404 | 5043 | POLICY_NOT_FOUND | 정책을 찾을 수 없음 |
| 500 | 5051 | PERMISSION_VERIFICATION_FAILED | 권한 검증 처리 실패 |
| 500 | 5052 | POLICY_EVALUATION_FAILED | 정책 평가 처리 실패 |
| 500 | 5099 | UNKNOWN_IAM_ERROR | 알 수 없는 IAM 관련 내부 오류 발생 |
9. 변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-06-13 | bok@weltcorp.com | 최초 작성 - 서비스 간 인증, Service Account 관리, 권한/역할/정책 관리 API 엔드포인트 정의 |
| 0.2.0 | 2025-10-27 | assistant | identityLevel 기반 인가 평가 API 추가, 사용자 권한 응답에 identityLevel 필드 포함 |