---
title: 토큰 관리
description: 앱 소유자가 웹 세션으로 에이전트 토큰을 발급·조회·철회하는 API.
---

# 토큰 관리

에이전트 토큰은 개발자 콘솔의 **앱 정보 및 SDK → 코딩 에이전트 연결**에서 관리할 수 있습니다. 이 페이지는 같은 기능을 구현하는 웹 클라이언트를 위한 API 명세입니다.

모든 토큰 관리 엔드포인트는 **앱 소유자의 웹 로그인 세션**이 필요합니다. 에이전트 토큰으로 새 토큰을 만들거나 다른 토큰을 조회·철회할 수 없습니다. `Authorization` 헤더를 보내면 `401`로 거부합니다. 변경 요청에는 허용된 웹 `Origin`도 필요합니다.

## 토큰 발급

```http
POST /api/v1/apps/:appId/automation/tokens
Content-Type: application/json
```

| 필드            | 필수   | 제약                                          |
| --------------- | ------ | --------------------------------------------- |
| `name`          | 예     | 앞뒤 공백 제거 후 1–100자                     |
| `expiresInDays` | 아니요 | 정수 1–90. 기본 30일                          |
| `scopes`        | 아니요 | 지원 권한 1–3개, 중복 불가. 기본 세 권한 모두 |

지원 권한은 `feedback:read`, `work-items:read`, `work-items:write`입니다.

다음 코드는 로그인한 서비스와 같은 Origin에서 실행하는 웹 클라이언트 예시입니다. 문서 도메인에서 실행하는 예시가 아닙니다. 브라우저가 세션 쿠키와 `Origin`을 전송합니다.

```js
const appId = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"; // 실제 앱 ID
const response = await fetch(`/api/v1/apps/${appId}/automation/tokens`, {
  method: "POST",
  credentials: "same-origin",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "개발 머신 MCP",
    expiresInDays: 30,
    scopes: ["feedback:read", "work-items:read", "work-items:write"],
  }),
});
const result = await response.json();
if (!response.ok) throw new Error(result.message);
// result.token은 이 응답에서만 제공됩니다. 로그나 저장소에 기록하지 마세요.
```

응답 `201`의 구조입니다. `token` 값은 설명용 자리표시자입니다.

```json
{
  "token": "ot_agent_REDACTED",
  "tokenInfo": {
    "id": "ffffffff-ffff-4fff-8fff-ffffffffffff",
    "name": "개발 머신 MCP",
    "scopes": ["feedback:read", "work-items:read", "work-items:write"],
    "expiresAt": "2026-11-27T02:00:00.000Z",
    "createdAt": "2026-10-28T02:00:00.000Z",
    "lastUsedAt": null,
    "revokedAt": null
  }
}
```

토큰 원문은 서버에 해시로 저장되며 이 응답에서만 제공됩니다. 토큰 발급에는 `clientRequestId`가 없습니다. 응답이 유실되었다고 같은 요청을 반복하면 새 토큰을 추가로 발급합니다. 목록에서 불필요한 토큰을 확인해 철회하세요.

## 목록 조회

```http
GET /api/v1/apps/:appId/automation/tokens
```

`200` 응답은 `{ "tokens": [...] }`이며 각 항목은 위의 `tokenInfo` 형식입니다. 원문과 해시는 반환하지 않습니다. 최신 생성 순서로 만료·철회된 항목도 포함하며 페이지 나누기는 없습니다.

| 필드         | 의미                                      |
| ------------ | ----------------------------------------- |
| `id`         | 철회 요청에 쓰는 UUID                     |
| `name`       | 발급할 때 지정한 이름                     |
| `scopes`     | 부여한 권한 배열                          |
| `expiresAt`  | 만료 시각                                 |
| `createdAt`  | 발급 시각                                 |
| `lastUsedAt` | 마지막 토큰 인증 시각. 사용 전에는 `null` |
| `revokedAt`  | 철회 시각. 철회 전에는 `null`             |

시각은 UTC ISO 8601 문자열입니다. `lastUsedAt`은 토큰 인증 시각이며 개별 API 작업의 성공 여부를 의미하지 않습니다.

## 토큰 철회

```http
DELETE /api/v1/apps/:appId/automation/tokens/:tokenId
```

성공 응답 `200`:

```json
{ "ok": true }
```

이미 철회한 토큰에 같은 요청을 반복해도 성공합니다. 대상 앱에서 찾을 수 없는 토큰 ID는 `404`입니다. 철회 후에는 새 토큰을 발급해야 하며 기존 토큰을 되살리거나 만료 기간·권한을 변경하는 API는 없습니다.

토큰 유출이 의심되면 먼저 철회하고 새 토큰을 도구에 연결하세요. [MCP 연결](/mcp/)에서 실행 환경에 전달하는 방법을 확인할 수 있습니다.
