fix(ci): identify denied organization roots in access checks

Log the requested tenant, endpoint, operation and exposure for organization HTTP 401/403 responses. Keep credentials and upstream response bodies out of diagnostics and retain the deployment gate.

Validation: source checks and 118 tests pass, including forbidden-root identification and diagnostic privacy coverage.
This commit is contained in:
root committed 2026-11-11 11:35:36 +09:00
1 parent 7c09c89da5
commit bed970a175
3 files changed
+46 -1

No files matched your search

+2
View File
@@ -147,6 +147,8 @@ Gitea의 스테이징 설정을 `.gitea/workflows/deploy.yml`에서 Worker 런
기본 `ORG_CONTEXT_ENABLED=false`에서는 조직 API를 호출하지 않습니다. `true`로 배포하면 `npm run org:verify`가 실제 키로 조직 API를 먼저 검증하며, 실패 시 새 Worker 배포를 진행하지 않습니다. 성공 시에는 조직·사용자·소속 건수만 로그에 출력합니다. 전체 응답·전화번호·키 원문은 출력하지 않습니다.
배포 전 검증에서 HTTP 401/403이 발생하면 요청한 API 주소·기준 tenant UUID·OperationID `baron.org-context.read`·exposure `identifiers`를 함께 출력합니다. 키 원문과 API 응답 본문은 출력하지 않습니다. 403이면 발급 서버의 API 키 관리에서 이 작업·노출 단계·해당 tenant subtree 조회 범위를 확인합니다. 여러 기준 tenant 중 하나만 거부돼도 전체 검증은 실패하며, 권한 밖 조직을 임의로 제외하거나 검증을 건너뛰지 않습니다.
Worker는 서명된 세션의 사용자 UUID로 소속을 찾습니다. 조회 조직 컨텍스트·대표 소속을 선택하고, 기존 requester ID·tenant ID·권한은 유지합니다. 새 문의는 `requester_affiliation`에 회사, `requester_department`에 부서를 저장합니다. JSON과 첨부 multipart에 같은 값을 사용합니다. 목록·상세는 글에 저장된 정보를 사용하며 조회 시점의 조직으로 과거 글을 바꾸지 않습니다.
조직 조회가 실패하면 기존 세션·글쓰기 흐름과 확인된 SSO 정보를 유지합니다. 누락되거나 모호한 사용자는 `orgContextStatus`로 구분하고 다른 작성자의 정보를 대신 쓰지 않습니다. 로그인 후 `/auth/session`의 `user.orgContextStatus=unavailable`이면 `user.orgContextError`에서 허용된 오류 코드만 확인할 수 있습니다. `org_context_missing_credentials`는 Worker의 조직 API 키 누락, `org_context_http_401`은 API 인증 거부, `org_context_http_403`은 API 접근 거부, `org_context_timeout`은 요청 시간 초과를 뜻합니다. 알 수 없는 오류는 `org_context_unavailable`로 표시하며 키·원본 오류 메시지·조직 디렉터리는 응답에 넣지 않습니다. 조회가 정상화되면 이전 `orgContextError`는 제거됩니다. HTTP 200이나 요청 로그의 `outcome=ok`만으로 조직 조회 성공을 판단하지 않습니다.