작업 내용 저장
This commit is contained in:
@@ -30,18 +30,6 @@
|
||||
- `GET /auth/tokens`
|
||||
- `POST /auth/tokens`
|
||||
- `DELETE /auth/tokens/{token_id}`
|
||||
- `POST /auth/bots`
|
||||
- `GET /auth/bots`
|
||||
- `GET /auth/bots/{bot_id}`
|
||||
- `POST /auth/bots/{bot_id}/tokens`
|
||||
- `GET /auth/bots/{bot_id}/tokens`
|
||||
- `DELETE /auth/bots/{bot_id}/tokens/{token_id}`
|
||||
- `DELETE /auth/bots/{bot_id}`
|
||||
- `POST /auth/me/bots`
|
||||
- `GET /auth/me/bots`
|
||||
- `POST /auth/me/bots/{bot_id}/tokens`
|
||||
- `GET /auth/me/bots/{bot_id}/tokens`
|
||||
- `DELETE /auth/me/bots/{bot_id}/tokens/{token_id}`
|
||||
|
||||
### 포트폴리오
|
||||
- `GET /portfolios`
|
||||
@@ -463,55 +451,23 @@ curl -X POST "http://localhost:8000/auth/tokens" \
|
||||
-d '{"name": "cli", "permission": "trade-write", "expires_in_days": 30}'
|
||||
```
|
||||
|
||||
#### 봇 주체와 봇 토큰
|
||||
- `POST /auth/bots`: admin only, `CreateBotPrincipalRequest` -> `BotPrincipalResponse`
|
||||
- `GET /auth/bots`: admin only, `is_active` 필터 지원
|
||||
- `GET /auth/bots/{bot_id}`: admin only
|
||||
- `DELETE /auth/bots/{bot_id}`: admin only, bot 비활성화 및 연결 토큰 revoke, 응답 `200`
|
||||
- `POST /auth/bots/{bot_id}/tokens`: admin only, `CreateBotTokenRequest` -> `IssuedBotTokenResponse`
|
||||
- `GET /auth/bots/{bot_id}/tokens`: admin only, `AuthTokenResponse[]`
|
||||
- `DELETE /auth/bots/{bot_id}/tokens/{token_id}`: admin only, `204`
|
||||
#### 서비스 토큰 관리 (CLI 전용)
|
||||
|
||||
소유권/권한 제약:
|
||||
서비스 토큰은 CLI를 통해서만 발급/폐기한다. HTTP API 경로는 제공하지 않는다.
|
||||
|
||||
- bot principal은 `owner_user_id`를 필수로 가진다.
|
||||
- bot permission은 `read` 또는 `trade-write`만 허용한다.
|
||||
- bot 토큰 인증 컨텍스트의 실효 `user_id`는 bot owner(`owner_user_id`)로 해석된다.
|
||||
|
||||
#### 사용자 전용(Self-service) 봇 관리
|
||||
- `POST /auth/me/bots`: DB-issued `read` 이상 사용자 토큰, `CreateSelfBotPrincipalRequest` -> `BotPrincipalResponse`
|
||||
- `GET /auth/me/bots`: DB-issued `read` 이상 사용자 토큰, 본인 소유 bot 목록
|
||||
- `POST /auth/me/bots/{bot_id}/tokens`: DB-issued `read` 이상 사용자 토큰, `CreateBotTokenRequest` -> `IssuedBotTokenResponse`
|
||||
- `GET /auth/me/bots/{bot_id}/tokens`: DB-issued `read` 이상 사용자 토큰, `AuthTokenResponse[]`
|
||||
- `DELETE /auth/me/bots/{bot_id}/tokens/{token_id}`: DB-issued `read` 이상 사용자 토큰, `204`
|
||||
- `pfhub service-token issue <name> --user <username> [--permission read|trade-write] [--ttl-days N | --no-expiry]`
|
||||
- `pfhub service-token revoke <name> [--force]`
|
||||
|
||||
제약:
|
||||
|
||||
- `/auth/me/bots*` 경로는 요청자 본인 소유 bot(`owner_user_id == auth_context.user_id`)에만 허용된다.
|
||||
- 타 사용자 소유 bot 접근 시 `403`.
|
||||
- 서비스 토큰 이름은 전체 서비스 토큰 내에서 유일하다.
|
||||
- 귀속 사용자(`--user`)가 존재하지 않으면 발급 실패이다.
|
||||
|
||||
대표 요청:
|
||||
대표 실행:
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/auth/bots" \
|
||||
-H "Authorization: Bearer <ADMIN_TOKEN>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "rebalance-bot", "owner_user_id": "user-1", "permission": "trade-write", "description": "nightly jobs"}'
|
||||
|
||||
curl -X POST "http://localhost:8000/auth/bots/bot-1/tokens" \
|
||||
-H "Authorization: Bearer <ADMIN_TOKEN>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "nightly", "permission": "trade-write", "expires_in_days": 90}'
|
||||
|
||||
curl -X POST "http://localhost:8000/auth/me/bots" \
|
||||
-H "Authorization: Bearer <USER_TOKEN>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "my-bot", "permission": "read", "description": "personal automation"}'
|
||||
|
||||
curl -X POST "http://localhost:8000/auth/me/bots/bot-1/tokens" \
|
||||
-H "Authorization: Bearer <USER_TOKEN>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "personal-key", "permission": "read", "expires_in_days": 30}'
|
||||
pfhub service-token issue nightly --user alice --permission trade-write --ttl-days 365
|
||||
pfhub service-token revoke nightly --force
|
||||
```
|
||||
|
||||
### 사용자
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
| --- | --- |
|
||||
| `read` | 조회 계열 API |
|
||||
| `trade-write` | 조회 + 포트폴리오 변경 API |
|
||||
| `admin` | 전체 API + 사용자/봇 관리 |
|
||||
| `admin` | 전체 API + 사용자/서비스토큰 관리 |
|
||||
|
||||
소유권 결합 정책:
|
||||
|
||||
@@ -31,51 +31,42 @@
|
||||
|
||||
## 인증 소스
|
||||
- 환경변수 기반 정적 토큰: `PORTFOLIOHUB_*_TOKENS`
|
||||
- DB 저장 토큰: 로그인 세션/클라이언트 토큰/봇 토큰
|
||||
- DB 저장 토큰: 로그인 세션 토큰 / 클라이언트 토큰 / 서비스 토큰
|
||||
|
||||
봇 토큰 사용자 컨텍스트 정책:
|
||||
서비스 토큰 사용자 컨텍스트 정책:
|
||||
|
||||
- 봇 principal은 `owner_user_id`를 가진다.
|
||||
- 봇 토큰 인증 시 실효 사용자 식별자는 `bot_principals.owner_user_id`로 해석한다.
|
||||
- 따라서 소유권이 필요한 포트폴리오 API에서 봇 토큰은 소유 사용자 경계 내에서만 동작한다.
|
||||
- 서비스 토큰은 특정 사용자(`user_id`)에 귀속되며 `token_type = 'service'`로 식별된다.
|
||||
- 토큰 이름(`name`)은 서비스 토큰 내에서 유일하며 CLI 관리의 기본 키로 사용된다.
|
||||
- 소유권이 필요한 포트폴리오 API에서 서비스 토큰은 귀속 사용자 경계 내에서만 동작한다.
|
||||
|
||||
## 봇 관리 API 정책
|
||||
## 서비스 토큰 CLI 관리
|
||||
|
||||
- Admin 경로:
|
||||
- `POST /auth/bots`
|
||||
- `GET /auth/bots`
|
||||
- `GET /auth/bots/{bot_id}`
|
||||
- `DELETE /auth/bots/{bot_id}`
|
||||
- `POST/GET/DELETE /auth/bots/{bot_id}/tokens*`
|
||||
- Self-service 경로(사용자 본인 전용):
|
||||
- `POST /auth/me/bots`
|
||||
- `GET /auth/me/bots`
|
||||
- `POST/GET/DELETE /auth/me/bots/{bot_id}/tokens*`
|
||||
- `pfhub service-token issue <name> --user <username>` — 서비스 토큰 발급 (기본 TTL 365일)
|
||||
- `pfhub service-token revoke <name>` — 서비스 토큰 폐기
|
||||
|
||||
제약:
|
||||
|
||||
- self-service 경로는 DB 사용자 컨텍스트가 있는 사용자 토큰에서만 허용한다.
|
||||
- self-service 경로는 요청자의 소유 봇(`owner_user_id == auth_context.user_id`)에만 허용한다.
|
||||
- 봇 권한은 `read` 또는 `trade-write`만 허용한다.
|
||||
- `--ttl-days`와 `--no-expiry` 동시 사용은 거부한다.
|
||||
- 동일 이름의 서비스 토큰은 중복 발급할 수 없다.
|
||||
- `--user`로 지정한 사용자가 존재하지 않으면 발급 실패 처리한다.
|
||||
|
||||
## 토큰 라이프사이클
|
||||
1. 사용자 로그인(`POST /auth/login`) 또는 토큰 발급 API 호출
|
||||
2. 토큰 해시 저장 및 prefix 관리
|
||||
3. 요청 처리 시 해시 비교와 만료/폐기 상태 검증
|
||||
4. `DELETE /auth/tokens/{token_id}` 또는 봇 비활성화로 토큰 폐기
|
||||
4. `DELETE /auth/tokens/{token_id}` 또는 서비스 토큰 폐기(`pfhub service-token revoke`)로 토큰 폐기
|
||||
|
||||
CLI 봇 토큰 라이프사이클:
|
||||
서비스 토큰 라이프사이클:
|
||||
|
||||
1. `bot token issue <bot_id>` 실행 시 `--ttl-days`/`--no-expiry` 정책을 먼저 검증한다.
|
||||
2. 정책 검증 후 서비스 계층에서 권한과 만기 정책을 재검증한다.
|
||||
3. 발급 성공 시 응답은 마스킹된 토큰만 재출력 가능하며, 원문 토큰은 1회 출력 경로로 제한한다.
|
||||
4. `bot token revoke <bot_id> <token_id>` 실행 시 확인 프롬프트(`--force`로 생략 가능)를 거쳐 폐기한다.
|
||||
1. `pfhub service-token issue <name> --user <username>` 실행 시 `--ttl-days`/`--no-expiry` 정책을 먼저 검증한다.
|
||||
2. 정책 검증 후 서비스 계층에서 사용자 존재 및 이름 중복 여부를 검증한다.
|
||||
3. 발급 성공 시 원문 토큰은 1회만 출력된다.
|
||||
4. `pfhub service-token revoke <name>` 실행 시 확인 프롬프트(`--force`로 생략 가능)를 거쳐 폐기한다.
|
||||
|
||||
만기 정책:
|
||||
|
||||
- 기본 TTL은 365일이다.
|
||||
- `--ttl-days`와 `--no-expiry` 동시 사용은 거부한다.
|
||||
- 비관리자 컨텍스트에서는 `--no-expiry`를 거부한다.
|
||||
|
||||
감사 로그 정책:
|
||||
|
||||
@@ -96,9 +87,7 @@ CLI 봇 토큰 라이프사이클:
|
||||
|
||||
## Validation Notes
|
||||
- 만료된 토큰은 항상 인증 실패로 처리해야 한다.
|
||||
- 비활성 봇(`is_active=false`)의 토큰은 거부되어야 한다.
|
||||
- 권한 계층 승격 우회가 없는지 API/CLI 양쪽에서 검증한다.
|
||||
|
||||
## Open Implementation Points
|
||||
- 정적 토큰과 DB 토큰의 우선순위/병합 정책을 명문화할지 결정한다.
|
||||
- 감사 로그(audit trail)에 토큰 발급/폐기 이벤트를 표준 포맷으로 남길지 확정한다.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
| --- | --- | --- |
|
||||
| DB 운영 | `init-db`, `migrate-db`, `health-check` | 스키마 적용 및 연결 상태 점검 |
|
||||
| 사용자 관리 | `user list/get/create/update/delete` | 운영 계정 라이프사이클 |
|
||||
| 서비스 토큰 관리 | `service-token issue/revoke` | 서비스 통합용 장기 토큰 관리 |
|
||||
| 포트폴리오 조회 | `portfolio list`, `portfolio status` | 상태 확인 |
|
||||
| 포트폴리오 변경 | `portfolio create/update/buy/sell/invest/transfer/reset/delete` | 거래/자금/상태 변경 |
|
||||
|
||||
@@ -53,6 +54,11 @@
|
||||
- `portfoliohub strategy update <strategy_set_id> [--name ...] [--config ...]`
|
||||
- `portfoliohub strategy delete <strategy_set_id> [--force]`
|
||||
|
||||
서비스 토큰 하위 명령:
|
||||
|
||||
- `portfoliohub service-token issue <name> --user <username> [--permission read|trade-write] [--ttl-days N] [--no-expiry]`
|
||||
- `portfoliohub service-token revoke <name> [--force]`
|
||||
|
||||
## 실행 원칙
|
||||
- 쓰기 명령은 기본적으로 확인 프롬프트를 띄운다.
|
||||
- 자동화 스크립트에서는 `--force`를 사용해 비대화식 실행을 보장한다.
|
||||
|
||||
Reference in New Issue
Block a user