# 아이서티 관제 재로그인: 사람이 따라 하는 가이드

현재 결과: 2026-09-21 기존 저장 비밀번호로는401이었고, 동료의 비밀번호 변경 확인 뒤
사용자가 제공한 새 값으로1회 로그인에 성공했다. 현장 private 비밀번호/세션의 정합과
Sidecar ready200/auth오류없음을 확인했다. WSS는90초내연결미확인으로 별도대기다.
로그인에 성공했으므로 WSS 확인을 위해 로그인 명령을 반복하지 않는다.
비밀번호 원문은 문서/화면/로그에 공유하지 않는다.

## 전체 흐름

```text
나: test 서버 root 터미널에서 명령 실행
 -> SSH: 아이서티 AI의 si 계정으로 전달
 -> AI: 저장된 계정/CA/접속정보를 읽음
 -> AI: 관제 POST /api/v1/auth/login 요청 1회
 -> 관제: 성공이면 새 token, 실패이면 오류 반환
 -> AI: 성공 token 저장 후 인증 Sidecar 재개
 -> 관제와 WSS 연결 확인
```

비유하면 로그인은 AI가 관제에 출입증을 새로 받는 절차다. Sidecar는 그 출입증을 쓰는
인증 담당 서비스다. 새 출입증을 파일에만 저장하고 서비스가 옛것을 계속 쓰지 않도록
Sidecar를 잠시 멈춘 뒤 로그인하고 다시 기동한다. Analytics/모델/카메라는 재시작하지 않는다.
제어와 Event 전송은 잠시 사용할 수 없으므로 카메라를 Stop한 시간에 수행한다.

이미 설정된 현장 계정/Redis 정보/CA를 재사용한다. 새 CA/CSR 발급, Redis ACL 변경,
카메라 Start, test 계정 복사는 하지 않는다. 이 도구는 아이서티 대상 전용이며 일반 서버용이 아니다.

## 1. 내가 실행하는 터미널 확인

실행 장소는 **test 서버 root 터미널**이다. Windows PowerShell이나 관제 브라우저가 아니다.

```bash
whoami
hostname
```

이 현장의 예상값은 `root`, `SSIMSAI98`이다. 다르면 여기서 멈춘다.
아래 연결 설정에는 비밀번호가 없다. 이미 승인된 SSH key/known_hosts를 사용한다.

```bash
ICERTI_SSH=(ssh -i /root/.ssh/ltb1021_contextra_icerti_si_ed25519
  -p 1023 -o BatchMode=yes -o StrictHostKeyChecking=yes
  -o UserKnownHostsFile=/root/.ssh/contextra_icerti_known_hosts
  -o ConnectTimeout=8 si@58.233.207.31)
"${ICERTI_SSH[@]}" 'docker ps --filter name=contextra-icerti --format "{{.Names}} {{.Status}}"'
```

Sidecar가 실행 중이어야 한다. SSH/권한 오류가 나오면 중단한다. host key 검증을 끄거나
sudo 비밀번호를 명령에 적지 않는다. 현재 si는 Docker 그룹 권한이 있어 sudo가 필요 없다.
`healthy`만으로 로그인/WSS 성공을 판단하지 않는다.

## 2. 로그인 1회 실행

관제의 AI-01 계정이 활성 상태이고 저장된 비밀번호가 맞는지 확인한 뒤 실행한다.
이 도구는 저장된 비밀번호를 사용한다. 계정이 바뀌면 먼저 비공개 경로의 현장 값 갱신을 요청한다.
새 비밀번호로 성공한 세션은 비밀번호 파일도 일치해야 다음 Sidecar 기동에서 재사용할 수 있다.
툴은 기존 image로 작은 일회성 helper를 사용한다. pull/build/설치 없이 CPU1/RAM512MiB로
제한하며 비밀값을 출력하지 않는다. 이전 세션은 AI의 기존 session 폴더에 mode600 백업한다.

```bash
"${ICERTI_SSH[@]}" 'python3 -B -' < \
  /workspace/contextra-analytics-runtime-lifecycle-refactor/tools/icerti_login_once.py
```

내가 입력하는 것은 이 명령뿐이다. AI가 내부 파일에서 loginId/password/advertisedIp/controlPort/
Redis reader/bboxStreamKey/aiControlCa를 읽어 기존 endpoint로 보낸다. 비밀번호를 다시 입력하거나
복사하지 않는다. 공식 Auth/Transport로 TLS 검증과 로그인 응답 계약을 확인한다.

### 성공했을 때의 예시 화면 (설명용, 이번 실제 결과 아님)

```text
{"phase":"preflight","auth":null,"wss":false}
{"phase":"login","login":"PASS", ...}
{"phase":"complete","login":"PASS","wss":{"connected":true, ...}, ...}
```

`login PASS`는 계정 인증/세션 저장 성공, `complete`와 `connected:true`는 WSS 재연결 확인이다.
이후 관제 화면에서 연결 상태를 확인한다. 실제 카메라/Redis 소비/Event 시연 성공과는 별개다.
complete 없이 종료됐으면 이미 로그인했을 수도 있으므로 무작정 재실행하지 않는다.

## 3. 실패했을 때: 반복 클릭하지 않기

비밀번호 변경 사실을 알기 전의 실제 결과는 다음과 같다.

```text
LOGIN_REJECTED
http_status: 401
LOGIN_FAILED_OR_UNKNOWN_NO_RETRY
sidecar_running: false
```

뜻: HTTPS 요청은 관제에 도착했지만 로그인 인증을 거부했다. 계정 비활성/비밀번호 불일치 등
구체적인 원인은401만으로 확정할 수 없다. 계정/비밀번호를 추측해 바꾸거나 TLS를 끄지 않는다.
로그인 실패 시 Sidecar는 중지 상태로 남는다. 다음 명령은 새 로그인 재시도가 아니라
**직전 백업과 동일하고 만료되지 않은 기존 세션**인지 확인한 뒤 원래 서비스를 복원한다.

```bash
"${ICERTI_SSH[@]}" 'python3 -B -' < \
  /workspace/contextra-analytics-runtime-lifecycle-refactor/tools/icerti_restore_saved_session.py
```

예상: `original_session_unchanged:true`, `original_sidecar_started:true`, `manual_login_retry:false`.
이 복원도 실패하면 멈추고 오류만 전달한다. 다른 토큰 복사나 강제 세션 덮어쓰기는 하지 않는다.
이 명령은 기존 파일이 유효함을 확인하는 것이며, 관제가 그 토큰을 여전히 인정한다는 보장은 아니다.

| 보이는 결과 | 내가 할 일 |
| --- | --- |
| 401 / LOGIN_REJECTED | 관제 담당자에게 AI-01 활성 상태/비밀번호 변경 여부 확인. 비밀번호는 비공개 경로로 전달 |
| UPSTREAM_TLS_INVALID | CA/주소/인증서 확인 요청. `-k` 금지 |
| UPSTREAM_OUTCOME_UNKNOWN | 응답만 유실됐을 수 있으므로 재시도하지 말고 결과 확인 요청 |
| LOGIN_PASS_WSS_NOT_CONFIRMED_NO_RELOGIN | 로그인은 성공했으므로 재로그인하지 말고 WSS 확인 요청 |
| SSH/권한/설정 오류 | 해당 오류에서 중단. sudo/host key/인증 우회 금지 |

## 4. 시뮬레이션 두 가지

**정상 상황:** 계정 확인 -> 1회 실행 -> login PASS -> complete/connected true -> 끝.
별도 endpoint 반복 호출이나 인증서 발급은 필요 없다.

**이번 같은401 상황:** 1회 실행 -> 401 -> 기존 세션 복원 -> 담당자에게 계정 상태 확인 ->
변경 근거가 생기고 재시도 승인 후에만 다시1회. 같은 실패를 반복하지 않는다.

도구의401 실패 및 기존세션 복원은 현장에서 실행 확인했다. 이후 새 비밀번호를 사용한
동일 Auth/Transport 로그인과 세션저장/Sidecar복원은PASS, WSS 전체경로는미확인이다.
WSS가false이면 관제측 AI 연결 상태/재연결 기능과 AI접근주소를 확인하도록 담당자에게 요청한다.
그 UI의 정확한 메뉴명과 내부 재시도 정책은 이 가이드에서 추정하지 않는다.
