End-to-End Deployment & Operations Guide · 2026-09-21

GitHub Enterprise Server
설계·설치부터 Entra 연동·CI/CD·운영까지

VMware 기반 GHES를 주 경로로, Microsoft Entra ID의 SAML·SCIM, GitHub Enterprise 라이선스·Connect, Azure Blob Storage·자체 호스팅 Runner, 백업·복구·업그레이드·장애 대응을 단계별로 연결합니다. 전체 구조를 먼저 이해한 뒤 12단계의 준비값 → 조작 → 화면 → 완료 조건을 따라갑니다.

GitHub Enterprise ServerVMware / Azure Entra SAML + SCIMActions + Azure Blob 절차 기준 GHES 3.213.22 차이 별도 확인 일반 기업용12단계 화면 안내
문서의 범위와 사용 원칙

특정 사용자·회사·프로젝트를 전제하지 않는 범용 구축·운영 안내입니다. 개인 이름·실제 테넌트/서버 식별자·내부 대화 이력은 포함하지 않습니다. 호스트는 github.example.com, 식별자는 예시입니다. 실제 값·권한·승인·설치 버전으로 바꾼 뒤 사용하세요. 공식 캡처의 데모 계정·ID는 설명용이며 실제 입력값이 아닙니다.

이 문서의 읽는 순서

① 아래 전체 구조도 → ② 12단계 실행 안내 → ③ 필요한 Phase의 상세 명령 → ④ 운영 인수 체크. 이미 구축된 경우는 신규 사용자 추가 순서 또는 증상별 진단으로 바로 이동합니다.

전체 흐름과 적용 경계

인프라·보안 담당

VM·스토리지·DNS·TLS·NTP·방화벽·백업·복구 경로를 준비합니다.

Entra·GitHub 관리자

서로 다른 관리 계정·SAML·SCIM·조직 권한·좌석의 경계를 구성합니다.

DevOps·운영 담당

Runner·Actions·Packages와 모니터링, 변경 관리, 장애 인계를 검증합니다.

전체 아키텍처: GHES를 중심으로 신원·실행·저장소 분리 동일한 로컬 Excalidraw 도형 데이터로 생성한 설명용 SVG. 편집기 내보내기가 아니며 HTML의 Clawpilot 테마를 상속합니다. 전체 아키텍처: GHES를 중심으로 신원·실행·저장소 분리 실선: 주요 연결 방향 · 점선: 조건부/선택 연결 · 라이선스 파일 전달은 하단의 별도 절차 Microsoft Entra ID · Server와 Cloud는 서로 다른 통합 앱 GHES 앱 · Server 전용 SAML 인증 / SCIM 프로비저닝 GHEC EMU 앱 (선택) Cloud 전용 · GHES 앱과 별개 개발자 / 브라우저 HTTPS 443 · Git SSH 22 승인된 관리자 PC SSH 122 · 콘솔 8443 GHES 어플라이언스 로컬 영구 저장소 사설 관리 경로 GHEC (조건부) 계약별 사용량 집계 EMU 사용 여부 별도 ① SAML · 443 SCIM · 443 별도 SAML / SCIM 443 / 22 관리 ② 443 독립 백업 경계 · 운영 필수 GHES 백업 보관 외부 객체는 별도 보호 Self-hosted Runner 작업 폴링 / 실행 어플라이언스 밖 · 선택 443 · 작업 폴링 Azure Blob Storage Actions 객체 · 선택 GHES → Blob · 443 ③ 443 ① SAML: 브라우저가 GHES ↔ Entra 인증을 중개 · SCIM: Entra 서비스 → GHES 443 ② Connect: GHES → GHEC 사용량 보고 · 좌석/쿼터 동기화나 계정 복제 아님 ③ Runner → Blob 443: 구성별 확인 · OIDC 선택 시 외부 인증 서비스 → GHES 443 저장소 OIDC: GHES 발급자의 .well-known discovery / JWKS 외부 도달성 필요 (SCIM과 별개) 라이선스 파일 · 계약에 따른 발급 → 다운로드 → 업로드 계약별 발급처 Cloud 포털 / 계약 운영자 다운로드 라이선스 파일 관리 콘솔 업로드 GHES에 적용 Cloud가 GHES에 라이선스를 실시간 푸시하지 않음 · GHEC/EMU 연결과 파일 업로드는 별개 운영 전 독립 백업·복원 검증 필수 · GHES 로컬 디스크, 외부 Blob, Runner는 서로 다른 경계 설명용 개념도 · 실제 화면이나 고객 환경이 아님 · 연결은 주요 논리 흐름만 표시
설명용 개념도. GHES 중심의 구성 경계. Cloud·Entra·외부 Storage·Runner·백업은 별도 구성 요소이며 선택 기능은 지원 조건을 확인합니다.

구조도 읽기: SAML은 브라우저 로그인, SCIM은 Entra 서비스의 계정 생성·변경, 라이선스 파일은 서버의 한도·만료, Connect는 서버 사용량 보고입니다. Runner는 GHES 밖에서 작업을 실행하고 Blob에 작업 로그·artifact를 저장합니다. 화살표가 연결돼 있어도 해당 기능의 인증·권한·실제 통신이 자동으로 완료되는 것은 아닙니다.

먼저 구분해야 하는 제품과 계정

대상무엇을 하는가이 문서에서의 경계
GHES고객이 운영하는 가상 appliance. Git 저장소·협업·Actions 등을 고객 인프라에서 제공직접 패치·백업·네트워크·리소스·인증을 운영. 일반 Linux 서버처럼 패키지나 에이전트를 임의 설치하지 않음
GHEC / EMUGitHub 운영 Cloud 서비스 및 Cloud 관리형 사용자 방식GHES와 별도 계정·별도 SSO/SCIM 대상. Cloud EMU의 shortcode_admin·OIDC 화면을 GHES에 그대로 적용하지 않음
GitHub Connect조건에 맞는 Cloud Enterprise와 GHES 기능·라이선스 사용량 연결계정 자동 복제 또는 기존 GHES 라이선스 파일의 자동 좌석 증설이 아님
GitHub Copilot별도 구독·인증·정책을 가진 AI 개발 도구GHES를 설치한다고 Copilot 모델·Cloud Agent가 appliance 안에 설치되는 것은 아님

단계별 통과 기준

작업을 했다는 기억이나 체크 표시가 아니라 아래 증거로 판단합니다. 미사용 기능은 사유와 승인자를 남겨 N/A로 처리합니다.

Gate통과 증거미충족 시
G0 · 설계·승인제품·버전·배포 플랫폼·과금 모델, 담당·RPO/RTO·변경 창·사용자 범위 확정Trial/유료·Cloud/Server·기능별 비용 혼선부터 해소
G1 · 인프라 준비VM·별도 데이터 디스크, DNS·TLS 설계, 경로별 포트·외부 의존성·보안 승인사설 주소에 포트만 열고 연결된다고 간주하지 않음
G2 · 안전한 기본 설치실제 버전·유효 라이선스·FQDN/TLS·관리 콘솔·SSH·비상 계정 접근SSO/SCIM 활성화나 대량 사용자 할당 보류
G3 · 신원 인수해당 GHES Entra 앱 연결, 대표 사용자·운영 Owner 생성, SAML 로그인·회수 시험다른 대상의 성공 로그나 고정 대기 시간으로 통과 처리 금지
G4 · 권한·라이선스Org/Team·private 저장소 허용/거부, 소비 좌석, Connect 사용량·중복 집계(사용 시)Copilot 좌석·Cloud People 수와 GHES 용량을 분리
G5 · 선택 기능 E2EActions/Blob/Runner·artifact, Packages push/pull 등 선택한 기능의 실제 시험기본 서버 설치 완료와 기능 운영 완료를 구분
G6 · 운영 인수모니터링·비밀 회전·백업·격리 복원·업그레이드 계획·담당자 인수 증거운영 확대 보류 또는 제한 범위·잔여 위험을 승인

작업 분류와 문서 동작

표시뜻대표 예
조회고객 설정을 바꾸지 않는 확인. 인증·네트워크 권한과 결과의 민감성은 별도GET API, 라이선스 정보, 로그 범위 조회
로컬 세션·파일관리 PC 인증 컨텍스트나 증거 파일 생성az login, 제한된 디렉터리, CSV·번들 다운로드
승인 후 변경자원·권한·서비스·데이터·과금에 영향을 주는 작업Save settings, SCIM on-demand, 라이선스 적용, workflow 실행, Storage 쓰기
실행 안전장치

명령은 자동 실행되지 않습니다. 복사 전에 실행 위치·도구·인증 주체·실제 값을 확인합니다. 관리 SSH는 122/admin, Git SSH는 22, 관리 콘솔은 8443입니다. curl -k, SSH 호스트키 검증 해제, 전체 재프로비저닝·계정 삭제·인증 해제를 일반 해결책으로 쓰지 않습니다. 토큰·연결 문자열·비밀번호·개인키는 문서나 셸 이력에 넣지 않습니다.

삽화는 설명용 개념도이며 실제 구축 화면이 아닙니다. 공식 화면 이미지는 해당 문서의 예시로 별도 출처를 표시합니다. UI·명령·라이선스 조건은 설치 버전과 계약에 따라 달라질 수 있으므로 변경 전 해당 버전 원문을 재확인합니다.

명령 복사와 체크리스트는 문서 보조 기능입니다. 실제 고객 환경의 실행 결과가 아닙니다.

이제 시작: STEP 01 — 설계와 입력값 확정. 이미 설치된 환경은 먼저 실제 상태와 비상 접근을 확인하고 필요한 절만 적용합니다.

순서대로 따라 하는 12단계

아래 순서는 VMware 기반 GHES + Entra SAML/SCIM을 기준으로 합니다. Cloud 병용·Actions·Packages·Copilot은 계약과 사용 목적에 따라 선택합니다. 기존 환경에서는 처음부터 재설치하지 말고 현재 단계의 설정·증거를 읽은 뒤 필요한 변경만 승인받습니다.

진행 순서: 전체 구조 확인 후 12단계로 적용·검증 동일한 로컬 Excalidraw 도형 데이터로 생성한 설명용 SVG. 편집기 내보내기가 아니며 HTML의 Clawpilot 테마를 상속합니다. 진행 순서: 전체 구조 확인 후 12단계로 적용·검증 각 행은 왼쪽 → 오른쪽 · 행 끝 화살표를 따라 다음 행으로 이동 · 조건부/선택 항목은 N/A 가능 1–4 · 기반 01 · 설계/입력 범위·입력값 확정 신규 / 기존 배포 구분 02 · 라이선스확보 계약·발급 경로 확인 파일·좌석·만료 확인 03 · 네트워크준비 DNS·TLS·시간 확인 방향별 통신 승인 04 · GHES설치 어플라이언스 구성 기존 배포는 상태 검증 5–8 · 신원/연계 05 · EntraSAML GHES 전용 앱 구성 브라우저 로그인 검증 06 · SCIM파일럿 생성·갱신·비활성화 식별자·로그 검증 07 · Org/Team권한 조직·팀·저장소 권한 최소 권한 검증 08 · Connect(조건부) 사용량 보고 검증 미적용 시 N/A 9–12 · 선택기능/운영 09 · ActionsStorage (선택) 저장소 검증 미사용 시 N/A 10 · Runner/워크플로 (선택) 실행 검증 미사용 시 N/A 11 · Packages/Copilot (선택) 지원·자격 확인 미사용 시 N/A 12 · 운영인수 운영 전 백업·복원 검증 모니터링·책임 인계 적용 규칙 · 기존 배포도 같은 순서로 확인 기존 배포: 해당 단계의 현재 설정·증적을 검증 · 재설치하지 않음 조건부·선택 항목(8–11)은 미적용 시 N/A와 사유 기록 선택 기능을 건너뛰어도 운영 인수는 필수 · 운영 전 백업·복원 검증을 완료해야 함 설명용 개념도 · 실제 화면이나 고객 환경이 아님 · 연결은 주요 논리 흐름만 표시
설명용 개념도. 기반 → 신원·연계 → 선택 기능·운영 순서로 진행합니다. 기존 배포는 현재 설정을 검증하고, 미적용 선택 항목은 N/A로 기록합니다.
캡처를 읽는 방법

캡처는 Microsoft/GitHub 공식 문서의 실제 예제 화면입니다. 개인·특정 기업의 운영 화면은 사용하지 않습니다. 각 화면의 ① 클릭 위치 → ② 입력·대조 값 → ③ 확인 결과를 따라가며 예시 이름·ID·날짜·좌석은 복사하지 않습니다. 검증된 캡처가 없는 화면은 조작 경로와 입력표로 설명하고 실제 UI처럼 새로 그리지 않습니다.

STEP 01 / 12 · 기본 순서 · 조작 전 승인 확인

01. 설계와 입력값 확정

담당
설계·서비스·보안 책임자
준비값
업무 범위·계약·버전·담당 역할
작업 위치
승인된 설계·변경 작업표
  1. 사용 범위·버전·책임자 결정

    GHES 설치 버전·지원 패치, VMware/다른 플랫폼, 예상 사용자·Git/Actions 부하, Cloud 병용과 과금 모델을 결정합니다. 인프라·네트워크·Entra·GHES·DevOps·백업 담당 역할과 변경 승인자를 지정합니다.

  2. 비상 접근·변경 창·백업 계획 준비

    Console root 암호·관리 SSH 키의 보관·복구 담당을 정하고 RPO/RTO·백업 위치를 설계합니다. 기존 환경의 인증·라이선스를 바꾸기 전에는 현재 설정·유효한 백업·복구 접근을 확보합니다.

  3. 입력표 작성

    아래는 형식 예시입니다. 실제 값은 승인된 별도 작업표에 기록하고 토큰·개인키·암호는 비밀 저장소에 둡니다.

입력예시 또는 확인 위치혼동하지 않을 것
GHES FQDN / TLSgithub.example.com / SAN·전체 체인·만료일Cloud enterprise URL이나 IP로 대체하지 않음
VM / 디스크지원되는 이미지·승인 CPU/RAM·root / data 분리Runner를 GHES appliance에 설치하지 않음
DNS / NTP / proxy승인된 resolver·time server·HTTP proxy·예외사내 PC 접속 성공과 서비스 경로 성공은 다름
Cloud enterprise / 계약선택한 기업과 Volume / Metered / Trial계정 수·Copilot 좌석·Enterprise 소비·서버 키를 구분
Entra tenant / GHES 앱Tenant ID + Enterprise application Object IDApplication(client) ID 및 사용자 Object ID와 다름
일반 파일럿 / 운영 Owner승인된 소수 사용자 Object ID·직접 할당·역할앱 Owners와 GitHub app role을 구분
Storage / Runner실제 Blob endpoint·인증 모드 / OS·label·runner group선택하지 않으면 STEP 09–10은 N/A
다음 단계로 넘어갈 조건: 실제 입력값·권한·승인 범위가 정리되고 미사용 기능은 N/A로 합의됐습니다.

STEP 02 / 12 · 기본 순서 · 조작 전 승인 확인

02. 라이선스 확보

담당
청구·Cloud enterprise 관리자
준비값
계약 유형·필요 좌석·발급 대상 기업
작업 위치
GHEC Licensing 또는 계약별 다운로드
  1. 과금 모델에 맞는 발급 경로 선택

    Volume/Trial은 계약·Sales 또는 공식 Enterprise 다운로드 경로를 사용합니다. PAYG는 선택한 Cloud enterprise의 Licensing에서 consumed Cloud licenses를 확인합니다. Server-only 요구와 셀프서비스 발급 가능 범위가 다르면 Sales/Support에 먼저 확인합니다.

  2. Cloud에서 파일 생성·다운로드

    Cloud 프로필 → Enterprises → 대상 기업 → Billing and licensing → Licensing. Cloud 소비 증가 또는 키 만료 임박 안내가 있으면 Generate new license를 실행하고 Enterprise Server licenses → Download로 파일을 받습니다. 단순 다운로드가 용량 증설을 뜻하지는 않습니다.

  3. 후보 파일과 계약 대조

    발급 대상·한도·만료일을 확인하고 제한된 위치에 보관합니다. 신규 설치는 STEP 04에서 적용합니다. 기존 서버가 있다면 설치 키의 seats와 실제 seats_used/seats_available를 비교하고 후보 파일 읽기 검사를 사용합니다.

키 교체 여부

기존 유효 키에 충분한 잔여 좌석이 있으면 신규 사용자마다 교체하지 않습니다. 용량 확대·만료 갱신이 필요할 때 새 파일을 승인 후 적용합니다. License sync는 파일 한도를 늘리지 않습니다.

Cloud 발급 화면의 검증된 캡처는 수록하지 않았습니다. 위 메뉴 경로와 공식 문서의 현재 UI를 대조합니다.

다음 단계로 넘어갈 조건: 유효한 GHES용 파일과 필요한 한도·만료일이 확인됐고 발급 기록이 남았습니다.

STEP 03 / 12 · 기본 순서 · 조작 전 승인 확인

03. 네트워크·DNS·TLS 준비

담당
네트워크·PKI·보안 담당
준비값
FQDN·서브도메인·포트·연결 방향·최신 허용 목록
작업 위치
DNS·방화벽/LB·PKI·프록시 관리 화면
  1. 인바운드부터 출발지별 승인

    사용자 HTTPS 443/Git SSH 22, 관리망 SSH 122/Console 8443, Entra 서비스 → GHES SCIM 443을 각각 분리합니다. 실제 cloud의 최신 Entra 출발지·NAT/LB/WAF·반환 경로를 확인합니다.

  2. 외부 연결은 필요한 목적지만

    GitHub.com Connect는 GHES → github.com, api.github.com, uploads.github.com TCP 443. Blob은 실제 계정 endpoint, Storage OIDC면 토큰 서비스와 외부 discovery/JWKS 접근도 필요합니다. Runner의 별도 다운로드·패키지 목적지는 추가 검토합니다.

  3. DNS·TLS·시간·프록시 준비

    FQDN·subdomain isolation·SAN·체인을 맞추고 DNS/NTP를 준비합니다. 프록시 사용 시 GHES→프록시와 프록시→외부를 따로 확인합니다. 임시 broad egress는 담당·만료·회수 조건을 정하고 영구 운영으로 남기지 않습니다.

  4. 설치 후 실제 경로로 재시험

    아직 기동 전이면 규칙·DNS 설계까지만 완료로 기록합니다. STEP 04 이후 GHES 송신·Entra 수신 경로를 동일 UTC의 경계·HTTP 로그로 확인합니다. 노트북 성공이나 TCP LISTEN만으로 최종 통과시키지 않습니다.

다음 단계로 넘어갈 조건: 연결표가 승인됐고 설치 후 실제 서비스 경로 시험 항목·담당이 정해졌습니다.

STEP 04 / 12 · 기본 순서 · 조작 전 승인 확인

04. GHES 설치와 관리 접근

담당
가상화·GHES 운영자
준비값
승인 이미지·라이선스·DNS/TLS·Console/SSH 복구 준비
작업 위치
vSphere → GHES Management Console → 관리 SSH
  1. 지원 이미지로 VM 생성

    공식 OVA의 버전·무결성을 확인하고 Deploy OVF Template으로 배포합니다. 전원 투입 전 승인 자원·root 용량·별도 빈 data 디스크·네트워크 매핑을 대조합니다. OS를 따로 설치하지 않습니다.

  2. 최초 설정 보호·초기화

    설치 담당자만 접근하도록 제한한 뒤 전원을 켭니다. https://github.example.com/setup의 최초 설정에서 라이선스를 올리고 Console root 암호를 정합니다. FQDN·Time·TLS를 구성하고 승인된 Save settings → 적용 완료 후 첫 웹 관리자 계정을 즉시 생성합니다.

  3. 관리 접근 확인

    관리 SSH 공개키를 등록하고 ssh -p 122 admin@HOSTNAME으로 버전·시각·라이선스를 조회합니다. 웹 관리자, Console 자격, SSH admin을 서로 다른 접근으로 확인합니다. 기본 서비스·HTTPS·비상 로그인을 시험합니다.

  4. 기존 서버의 라이선스 갱신은 별도 경로

    재설치하지 않습니다. 아래 L1/L2처럼 Update license → License file → Upload를 사용하고 백그라운드 반영 후 한도·유효성을 재조회합니다. 전체 OS 재부팅을 자동 후속 단계로 추가하지 않습니다.

L1 · User licenses → Update license

공식 문서 원본 PNG · 확대 후 Esc로 축소
L1 · User licenses → Update license — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

기존 상태부터 읽습니다. GHES Enterprise settings → Settings → License에서 현재 좌석·만료일을 확인하고, 승인된 갱신 때만 Update license로 이동합니다.

② 입력 / 대조할 값 · Input

대상 GHES는 https://github.example.com 같은 승인된 호스트입니다. 발급 대상·좌석 수·유효기간을 계약 및 새 라이선스 파일과 대조합니다.

③ 확인할 결과 · Expected

같은 GHES의 라이선스 업로드 화면으로 이동합니다. 링크를 여는 것만으로 라이선스가 갱신되지는 않습니다.

예시 범위·주의: 진입 링크만 표시한 공식 예제입니다. Unlimited Licenses·소비 좌석·2024년 만료일은 예시이며 실제 사용 권한이나 현재 상태가 아닙니다.

L2 · License file 선택·업로드

공식 문서 원본 PNG · 확대 후 Esc로 축소
L2 · License file 선택·업로드 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

기존 라이선스를 먼저 확인합니다. 신규 설치·갱신 승인 후 License file을 선택하고 발급받은 .ghl 파일을 지정한 다음 Upload합니다.

② 입력 / 대조할 값 · Input

승인된 GHES용 라이선스 파일만 사용합니다. 파일 내용·계약 식별자·키는 문서나 공유 화면에 복사하지 않습니다.

③ 확인할 결과 · Expected

업로드 후 적용된 좌석·유효기간을 다시 확인합니다. 파일 선택 화면이나 버튼만으로 적용 성공을 판단하지 않습니다.

예시 범위·주의: 공식 예제의 Running version 3.17.3, No seat restrictions, Clustering enabled, 2026년 만료일은 설치 권장값이 아닙니다. 출처는 GHES 3.21 문서이나 원 캡처의 UI는 다를 수 있습니다.

다음 단계로 넘어갈 조건: 실제 버전·유효 키·HTTPS·관리 접근·비상 복구가 확인됐습니다. PAYG 등 계약상 Connect 선행 조건이 있으면 STEP 08의 연결을 이 시점에 먼저 확인합니다.

STEP 05 / 12 · 기본 순서 · 조작 전 승인 확인

05. Entra 앱·SAML 구성

담당
Entra 관리자 + GHES 관리자
준비값
비상 계정·앱 Object ID·파일럿·GHES FQDN
작업 위치
Entra Enterprise apps / GHES Authentication
  1. GHES 비상 계정부터 준비

    기존 계정 전환 영향을 검토하고 Phase 4의 절차로 built-in scim-admin·Console·SSH 복구 접근을 확보합니다. 기존 SAML에서 필요한 setup 옵션은 선택만 하지 말고 승인된 Save settings와 적용 성공까지 확인합니다.

  2. Entra의 대상 테넌트·앱 식별

    Enterprise applications에서 신규 승인 시 GitHub Enterprise Server 갤러리 앱을 추가합니다. (Legacy)는 사용하지 않습니다. 기존 앱이면 새로 복제하지 말고 정확한 Object ID와 목적지를 확인합니다. GHES SAML과 SCIM에는 동일한 GHES 앱을 사용하고 Cloud EMU 앱은 별개로 유지합니다.

S1 · Entra ID → Enterprise applications

공식 문서 원본 PNG · 확대 후 Esc로 축소
S1 · Entra ID → Enterprise applications — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

Entra 관리 센터에서 디렉터리를 확인한 뒤 Entra ID → Enterprise apps(Enterprise applications)를 엽니다.

② 입력 / 대조할 값 · Input

이번 GHES 인증·프로비저닝용 테넌트를 읽기 확인합니다. App registrations 목록과 구분합니다.

③ 확인할 결과 · Expected

대상 테넌트의 Enterprise application 목록으로 이동합니다.

예시 범위·주의: 메뉴 진입용 공식 캡처입니다. 신규 앱 생성이나 GHES 연결 완료를 보여주지 않습니다.

S2 · All applications에서 기존 GHES 앱 찾기

공식 문서 원본 PNG · 확대 후 Esc로 축소
S2 · All applications에서 기존 GHES 앱 찾기 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

Search by application name or object ID에서 승인된 기존 GHES 앱을 검색합니다. 신규 구축 승인이 있을 때만 New application으로 별도 진행합니다.

② 입력 / 대조할 값 · Input

앱 이름·Object ID와 SAML/SCIM 목적지를 대조합니다. Cloud EMU·Copilot 앱을 GHES 앱 대신 선택하지 않습니다.

③ 확인할 결과 · Expected

첫 검색 결과가 아니라, 대상 GHES와 연결된 앱의 Overview를 확인합니다.

예시 범위·주의: 목록·검색 위치 예시입니다. 화면의 앱명은 공식 fixture이며 운영 대상이 아닙니다. 조회 실패를 이유로 기존 앱을 복제하지 않습니다.

S3 · Overview: Application ID와 service principal Object ID

공식 문서 원본 PNG · 확대 후 Esc로 축소
S3 · Overview: Application ID와 service principal Object ID — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

선택한 Enterprise application → Overview에서 ID를 읽습니다.

② 입력 / 대조할 값 · Input

Application ID는 client ID입니다. 이 화면의 Object ID는 해당 테넌트의 service principal ID이며 App registrations의 Object ID와 다릅니다.

③ 확인할 결과 · Expected

SAML·SCIM용 앱과 조회한 service principal이 같은 대상임을 확인합니다.

예시 범위·주의: Exchange 공식 문서의 Room Booking Tool(RoomBookingTool) 앱 예시입니다. ID 위치 설명용 구형 Azure AD 화면이며 GHES 앱 또는 현재 테넌트의 캡처가 아닙니다.

  1. 인증 전환 전 일반 파일럿 할당

    Users and groups에서 승인된 일반 파일럿을 할당합니다. 기존 환경 전환이면 필요한 기존 사용자 범위도 검토합니다. 일반 사용자 생성 문제를 Owner 부여로 우회하지 않습니다.

F1 · Users and groups: 할당·Role 읽기

공식 문서 원본 PNG · 확대 후 Esc로 축소
F1 · Users and groups: 할당·Role 읽기 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

기존 Users and groups 목록을 먼저 읽습니다. 승인된 신규 할당만 Add user/group → 대상 선택 → Select → Select a role(제공될 때) → Assign으로 진행합니다.

② 입력 / 대조할 값 · Input

사용자/그룹 Object ID·직접 할당·그룹 직접 멤버·현재 Role을 대조합니다. Entra 앱 Owners와 GHES enterprise owner 앱 역할은 다릅니다.

③ 확인할 결과 · Expected

필요한 파일럿만 의도한 역할로 할당됩니다. 앱 할당만으로 GHES 사용자 생성이나 저장소 접근 완료를 선언하지 않습니다.

예시 범위·주의: Microsoft Entra SAML Toolkit 1 공식 fixture입니다. 할당 진입 화면만 보이며 사용자 선택창·확장된 Role 목록·최종 Assign 화면은 없습니다. 전원 Owner 부여나 임의 app role 생성은 하지 않습니다.

  1. SP URL과 claim 입력

    Single sign-on → SAML에서 아래 기본 URL·claim을 구성합니다. objectidentifier와 SCIM externalId는 같은 사용자 객체여야 하며 NameID와는 별도 필드입니다.

S4 · Basic SAML Configuration: GHES URL

공식 문서 원본 PNG · 확대 후 Esc로 축소
S4 · Basic SAML Configuration: GHES URL — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처 · GHES 3.21 SAML·SCIM 제품 기준
① 클릭할 위치 · Click

같은 GHES 앱 → Single sign-on → SAML에서 기존 값을 읽습니다. 신규 구축 또는 승인된 수정 때만 Basic SAML Configuration → Edit → Save합니다.

② 입력 / 대조할 값 · Input

Identifier (Entity ID): https://github.example.com | Reply URL (ACS): https://github.example.com/saml/consume | Sign on URL: https://github.example.com/sso. example.com은 설명용이며 실제 승인 호스트로 모두 일치시킵니다.

③ 확인할 결과 · Expected

Entity ID·ACS·Sign-on URL이 같은 GHES를 가리킵니다. Cloud의 /enterprises/slug나 Entra tenant ID를 GHES Entity ID로 넣지 않습니다.

예시 범위·주의: 공식 기본 설정 예시이며 현재 대상의 저장 결과가 아닙니다. 기존 인증을 변경하기 전에 비상 접근과 파일럿·되돌리기 절차를 준비합니다.

S5 · Attributes & Claims: NameID와 objectidentifier

공식 문서 원본 PNG · 확대 후 Esc로 축소
S5 · Attributes & Claims: NameID와 objectidentifier — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처 · GHES 3.21 SAML·SCIM 제품 기준
① 클릭할 위치 · Click

Attributes & Claims → Edit에서 기존 매핑을 읽습니다. 변경·저장은 승인된 신규 구성 또는 수정일 때만 수행합니다.

② 입력 / 대조할 값 · Input

Unique User Identifier(NameID)·UPN과 별개로 http://schemas.microsoft.com/identity/claims/objectidentifier → Entra 사용자 Object ID → SCIM externalId의 일치를 대조합니다.

③ 확인할 결과 · Expected

같은 사용자 객체가 SAML과 SCIM에서 연결됩니다. 표시 이름·메일·NameID가 같다는 이유만으로 externalId가 맞다고 판단하지 않습니다.

예시 범위·주의: 기본 claim 일부만 표시한 공식 예시입니다. objectidentifier가 안 보인다고 없다고 단정하지 말고 상세 설정을 읽으세요. administrator=true 예제를 무조건 적용하거나 Owner를 강제 부여하지 않습니다.

  1. IdP 인증서·URL을 GHES에 연결

    Base64 공개 인증서, Login URL, Microsoft Entra Identifier를 수집해 GHES Management Console → Authentication → SAML의 Verification certificate·Single sign-on URL·Issuer에 연결합니다. 변경 승인 후 저장·적용 완료를 확인합니다. 아래 캡처는 Entra 값 위치이며 GHES 화면을 재구성한 것이 아닙니다.

S6 · SAML Signing Certificate: Base64 공개 인증서

공식 문서 원본 PNG · 확대 후 Esc로 축소
S6 · SAML Signing Certificate: Base64 공개 인증서 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처 · GHES 3.21 SAML·SCIM 제품 기준
① 클릭할 위치 · Click

기존 활성 인증서·만료일을 읽고 SAML Signing Certificate → Certificate (Base64) → Download를 선택합니다.

② 입력 / 대조할 값 · Input

Thumbprint·유효기간·활성 서명키를 대조합니다. GHES SAML verification certificate용 공개 인증서이며 TLS 서버 인증서나 Federation Metadata XML과 다릅니다.

③ 확인할 결과 · Expected

승인된 구성에 사용할 공개 인증서를 준비합니다. 다운로드만으로 GHES 인증서가 교체되지는 않습니다.

예시 범위·주의: 인증서 다운로드 위치의 공식 예시입니다. 표시된 ID·만료일은 fixture입니다. 교체는 별도 승인 후 IdP 활성 키·GHES 신뢰·비상 접근을 함께 검증합니다.

S7 · IdP Login URL·Identifier → GHES SAML 설정

공식 문서 원본 PNG · 확대 후 Esc로 축소
S7 · IdP Login URL·Identifier → GHES SAML 설정 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처 · GHES 3.21 SAML·SCIM 제품 기준
① 클릭할 위치 · Click

SAML 하단 Set up [앱명]에서 기존 Login URL과 Microsoft Entra Identifier를 읽습니다. 승인된 구성 때만 해당 값을 GHES에 입력·저장합니다.

② 입력 / 대조할 값 · Input

Entra Login URL → GHES Single sign-on URL. Microsoft Entra Identifier → GHES Issuer. 이 IdP issuer는 https://github.example.com이라는 GHES Entity ID와 다릅니다.

③ 확인할 결과 · Expected

IdP URL·issuer·공개 인증서가 같은 테넌트/앱 설정과 맞습니다. 승인된 저장 후 SCIM 대상 사용자의 프로비저닝을 먼저 확인하고 별도 브라우저로 파일럿 SSO를 시험합니다.

예시 범위·주의: 공식 fixture의 tenant GUID·URL을 복사하지 않습니다. 이 캡처는 Entra 값 위치이며 GHES Save settings 또는 실제 SSO 성공 화면이 아닙니다.

다음 단계로 넘어갈 조건: SAML URL·issuer·인증서·파일럿 할당·복구 접근이 일치합니다. SCIM 활성 환경의 실제 SSO 완료는 STEP 06의 계정 생성 후 확인합니다.

STEP 06 / 12 · 기본 순서 · 조작 전 승인 확인

06. SCIM 파일럿·자동 동기화

담당
Entra 앱 운영자 + GHES 관리자
준비값
동일 GHES 앱·SCIM PAT·파일럿 Object ID·정확한 UTC
작업 위치
Entra Provisioning / GHES 계정·관리 SSH
  1. SCIM 자격·대상 설정

    승인된 GHES setup 계정의 classic PAT에 scim:enterprise를 사용합니다. 공식 절차대로 SCIM을 활성화하고 같은 Entra GHES 앱의 Automatic configuration에 GHES Tenant URL과 토큰을 입력합니다. 토큰은 금고에서 전달하며 문서·로그·캡처에 넣지 않습니다.

F2 · Provisioning: 기존 configuration 확인

공식 문서 원본 PNG · 확대 후 Esc로 축소
F2 · Provisioning: 기존 configuration 확인 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처 · GHES 3.21 SAML·SCIM 제품 기준
① 클릭할 위치 · Click

GHES 앱 → Provisioning에서 기존 configuration을 먼저 선택합니다. 신규 구축 승인 때만 New configuration을 사용합니다.

② 입력 / 대조할 값 · Input

앱·대상 URL·job 상태·마지막 주기와 Attribute mapping, Provisioning logs, Provision on demand 진입 위치를 확인합니다.

③ 확인할 결과 · Expected

SAML과 동일한 GHES 앱의 configuration을 식별합니다. 오류 진단을 위해 Start/Restart 또는 중복 configuration 생성을 하지 않습니다.

예시 범위·주의: 새 configuration 진입을 보여주는 Preview UI 예시입니다. 기존 job 실행 증거가 아닙니다. 구형 UI에서는 Automatic → Admin Credentials가 바로 보일 수 있습니다.

S8 · Admin Credentials: Tenant URL·Test Connection

공식 문서 원본 PNG · 확대 후 Esc로 축소
S8 · Admin Credentials: Tenant URL·Test Connection — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처 · GHES 3.21 SAML·SCIM 제품 기준
① 클릭할 위치 · Click

기존 configuration → Admin Credentials를 읽습니다. 승인된 연결 시험만 Test Connection으로 실행하고, 신규/변경 승인 때만 Create 또는 Save합니다.

② 입력 / 대조할 값 · Input

Tenant URL: https://github.example.com/api/v3/scim/v2. Secret Token: •••••••• (마스킹 유지·복사 금지). 신규 입력은 승인된 GHES setup user의 classic PAT(scim:enterprise)를 보안 경로로 취급하며 문서에 붙여넣지 않습니다.

③ 확인할 결과 · Expected

연결 시험의 UTC·결과를 기록합니다. 성공은 연결/인증 확인이지 사용자 생성·역할 반영 성공이 아닙니다.

예시 범위·주의: 빈 입력란의 공식 예시이며 실제 토큰은 없습니다. GHES 3.21의 /api/v3/scim/v2를 기준으로 하며 Learn의 축약 표기 /api/v3/scim, Cloud api.github.com/scim/v2/enterprises/…, 8443 콘솔 URL과 혼동하지 않습니다.

  1. 연결 시험 후 파일럿 범위·매핑 저장

    Test Connection 성공과 실제 GHES 수신 로그를 확인한 뒤 신규 구성의 Save/Create를 진행합니다. 사용자 externalId/userName/active/roles, 직접 할당·보안그룹 직접 멤버와 Scope를 확인하고 Sync only assigned users and groups 및 승인된 소규모 파일럿으로 제한합니다.

F3 · Properties: Scope·알림·삭제 방지

공식 문서 원본 PNG · 확대 후 Esc로 축소
F3 · Properties: Scope·알림·삭제 방지 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처 · GHES 3.21 SAML·SCIM 제품 기준
① 클릭할 위치 · Click

기존 Properties/Settings와 Attribute mapping을 읽습니다. 신규 또는 승인된 수정 때만 편집·Apply/Save합니다.

② 입력 / 대조할 값 · Input

Provisioning scope: Sync only assigned users and groups. 알림·accidental deletion threshold를 승인 정책과 대조합니다. 별도 매핑 상세에서 externalId, userName, active, roles 및 필터를 확인합니다.

③ 확인할 결과 · Expected

의도한 소규모 파일럿만 범위에 포함되고 역할·활성 상태·삭제 방지 조건이 설명됩니다. Scope 전체 확대나 전체 Restart를 기본 해결책으로 사용하지 않습니다.

예시 범위·주의: 공식 예제의 threshold 500과 Preview 상태는 권장값이 아닙니다. roles/externalId 상세 매핑 화면은 없으므로 재구성하지 않았습니다. 실제 앱이 제공하는 매핑·역할을 별도로 읽습니다.

  1. 일반 파일럿 한 명 온디맨드

    정확한 사용자 Object ID를 확인해 한 번 실행합니다. 계정 생성·수정·비활성화가 가능한 변경 작업입니다. 장기 bearer PAT 방식은 이를 위해 정상 자동 job을 Stop할 필요가 없습니다. 새 할당 전파에는 수 분 걸릴 수 있으며 통상 30초 미만 안내는 완료 SLA가 아닙니다.

F6 · Provision on demand: 승인된 파일럿 선택

공식 문서 원본 PNG · 확대 후 Esc로 축소
F6 · Provision on demand: 승인된 파일럿 선택 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

기존 GHES 앱 → Provision on demand에서 대상 한 명을 검색하고 Object ID·할당·범위·예상 작업을 읽습니다. 승인 후에만 Provision을 실행합니다.

② 입력 / 대조할 값 · Input

동명이인을 피하기 위해 사용자 Object ID로 대조합니다. 변경 전 active·역할과 예상 Create/Update/Disable 등 작업을 확인합니다.

③ 확인할 결과 · Expected

승인된 한 명의 실제 작업 결과를 열어 확인할 수 있어야 합니다. 온디맨드는 읽기 시험이 아니라 실제 계정 변경입니다.

예시 범위·주의: AHCustom 공식 fixture의 그룹 멤버 2명 선택 예시입니다. 단일 사용자 생성 화면이 아니며 두 명을 그대로 선택하라는 지시도 아닙니다. 메뉴·선택 흐름만 참고합니다.

F7 · Perform action·View details: 실제 작업 판정

공식 문서 원본 PNG · 확대 후 Esc로 축소
F7 · Perform action·View details: 실제 작업 판정 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

실제 파일럿의 온디맨드 결과에서 Perform action → View details를 읽습니다. 결과 확인만을 위해 다시 Provision하지 않습니다.

② 입력 / 대조할 값 · Input

Action·Status·Target ID·변경 속성·UTC를 대조하고 GHES SCIM identity, active, 역할을 별도로 확인합니다.

③ 확인할 결과 · Expected

실제 사용자 작업의 성공 후 파일럿 SAML 로그인·Org/저장소 권한을 따로 검증합니다. Skip이나 Test Connection 성공을 사용자 생성으로 해석하지 않습니다.

예시 범위·주의: AHCustom의 Group membership operations에서 두 멤버 추가를 보여주는 공식 fixture입니다. GHES 단일 사용자 생성 또는 Role 강제 반영 성공 캡처가 아닙니다.

  1. 프로비저닝 로그와 GHES를 대조

    해당 앱·사용자·실행 UTC의 Action/Status/Steps/Target ID를 읽습니다. Success/Create, Update, Disable/Delete, Skipped를 구분하고 GHES identity·active·SSO와 대조합니다. Entra Change ID를 GHES request ID로 간주하지 않습니다.

F4 · Provisioning logs: 대상·시각·Action·Status

공식 문서 원본 PNG · 확대 후 Esc로 축소
F4 · Provisioning logs: 대상·시각·Action·Status — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

Provisioning logs에서 실제 GHES 앱·사용자·할당 이후 시각으로 필터링하고 Status 전체를 읽습니다.

② 입력 / 대조할 값 · Input

사용자 Object ID·UTC·Create/Update/Disable/Delete/Skipped·오류 detail을 구분합니다. 성공만 필터링해 누락을 숨기지 않습니다.

③ 확인할 결과 · Expected

해당 사용자의 이벤트 유무와 작업 종류를 설명하고 같은 시각의 GHES 기록과 연결합니다. 로그가 없다고 재생성이나 Restart부터 하지 않습니다.

예시 범위·주의: Salesforce·Google 등 여러 앱의 공식 예제입니다. 보이는 이름·성공 건수는 fixture이며 실제 GHES 결과가 아닙니다.

F5 · Steps: 범위·매칭·대상 작업

공식 문서 원본 PNG · 확대 후 Esc로 축소
F5 · Steps: 범위·매칭·대상 작업 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

대상 provisioning 이벤트를 열고 Steps와 세부 속성을 읽습니다.

② 입력 / 대조할 값 · Input

범위 판정·매칭·실패 단계·Target ID·변경 속성·오류 detail을 대조합니다. Change ID와 GHES request ID가 같다고 가정하지 않습니다.

③ 확인할 결과 · Expected

동일 사용자의 동일 UTC 작업으로 원인을 좁힙니다. 읽기 진단과 승인된 복구 변경을 분리합니다.

예시 범위·주의: Box 대상의 성공 Steps 공식 예시입니다. GHES 성공 증거 또는 현재 장애 원인 캡처가 아닙니다.

  1. Owner·자동 동기화 검증 후 확대

    운영 Owner가 필요하면 비상 접근을 유지한 채 Disable administrator demotion/promotion 제어·역할 매핑을 상세 절차대로 조정·적용합니다. 승인된 파일럿 범위로 Start provisioning하고 정기 동기화의 실제 roles·GHES Owner·로그인을 확인합니다. 온디맨드 성공만으로 역할 동기화 완료를 판단하지 않습니다. 이미 Running이면 전체 Restart하지 않습니다.

다음 단계로 넘어갈 조건: 파일럿의 계정 생성·활성·SSO, 필요한 운영 Owner와 비상 접근이 확인됐고 자동 job 상태·오류 분기가 기록됐습니다.

STEP 07 / 12 · 기본 순서 · 조작 전 승인 확인

07. Org·Team·저장소 권한

담당
Organization·저장소 관리자
준비값
계정 생성·SSO 완료·프로젝트/보안 경계·팀 권한표
작업 위치
GHES Organization / Teams / Repository Settings
  1. 최소 권한 조직·팀 구성

    업무·보안 정책 경계에 맞춰 Organization을 정하고 base permission을 검토합니다. 프로젝트별 팀을 만들고 사용자 → SCIM 그룹 → 그룹 멤버 → GHES 팀 연결 순서로 확인합니다.

  2. 저장소 권한 부여

    Organization → Teams → 팀의 Identity Provider Groups에서 승인 그룹을 연결하고, 저장소 Settings → Collaborators and teams에서 Read/Write/Maintain/Admin을 업무별로 부여합니다. 기존 팀 전환은 멤버 제거·접근 상실 영향 검토 후 진행합니다.

  3. 허용·거부를 일반 계정으로 시험

    승인 사용자와 비허용 사용자를 분리해 Private 웹·Git 읽기를 확인합니다. Base permissions=None이 Internal 가시성까지 차단한다고 보지 않습니다. PR 승인·status check·CODEOWNERS 강제도 실제 실패 시험으로 확인합니다.

다음 단계로 넘어갈 조건: 일반 사용자의 허용·거부·그룹 회수 경로가 확인됐습니다. 관리자 공유 인증으로 대신 시험하지 않았습니다.

STEP 08 / 12 · 선택·조건부 · 조작 전 승인 확인

08. GitHub Connect·사용량 동기화

담당
GHES·Cloud enterprise 관리자
준비값
연결 자격·올바른 Cloud enterprise·개인정보/egress 승인
작업 위치
GHES GitHub Connect / GHEC Licensing
  1. 연결 자격·목적지부터 확인

    양쪽 enterprise 관리 권한·계약 자격·동일 사용자 매칭 방식을 확인합니다. GHES의 실제 egress·프록시·Cloud IP allowlist와 필요한 목적지 443을 검증합니다. 해당 계약에서 Connect를 요구하면 STEP 04 직후부터 이 조건을 충족시킵니다.

  2. Connect 연결 후 필요한 기능만

    GHES 프로필 → Enterprise settings → GitHub Connect → Enable GitHub Connect에서 올바른 Cloud enterprise와 연결합니다. 별도로 License sync → Enable을 선택합니다. 사용자 ID·이메일 등 데이터 전송 범위·수신지를 승인받습니다.

C1 · GitHub Connect: License sync → Enable

공식 문서 원본 PNG · 확대 후 Esc로 축소
C1 · GitHub Connect: License sync → Enable — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

Enterprise settings → GitHub Connect에서 기존 연결 대상과 License sync 상태를 읽습니다. Connect 연결·변경 승인 후에만 Enable을 선택합니다.

② 입력 / 대조할 값 · Input

같은 계약의 GHES와 Cloud enterprise 연결을 대조합니다. 주간 자동 사용량 보고와 GHES .ghl 파일 적용은 별개입니다.

③ 확인할 결과 · Expected

활성화 후 주간 GHES → Cloud 라이선스 사용량 보고를 Cloud 측 보고서에서 확인합니다. 활성화 버튼만으로 보고 완료를 판단하지 않습니다.

예시 범위·주의: 공식 원본은 License sync의 Enable 버튼만 보여줍니다. Sync now는 이 그림에 없습니다. 주간 사용량 동기화는 라이선스 키 갱신·좌석 증설·사용자 프로비저닝이 아닙니다.

  1. 사용량 전송과 키 적용을 각각 확인

    자동 사용량 전송은 주 1회입니다. 필요하면 Enterprise settings → Settings → License/Licensing → License sync → Sync now를 승인 후 실행합니다. Cloud Licensing의 해당 Server source·마지막 성공·중복 제거 결과를 확인합니다. 키의 한도·만료는 STEP 02/04와 별개입니다.

다음 단계로 넘어갈 조건: Enabled뿐 아니라 실제 사용량 전송·수신·중복 제거 증거가 있습니다. 미사용이면 계약·요구사항 확인 후 N/A로 기록합니다.

STEP 09 / 12 · 선택·조건부 · 조작 전 승인 확인

09. Actions·외부 Storage

담당
Azure Storage·Entra 앱 담당 + GHES 관리자
준비값
선택 인증 모드·계정 endpoint·네트워크·RBAC/federation
작업 위치
Azure Portal / Entra App registrations / GHES Actions
  1. 저장소·인증 방식 선택

    지원되는 Azure Blob 계정·실제 endpoint·네트워크 경로를 준비합니다. OIDC와 Credentials-based를 혼용하지 않습니다. Private Endpoint면 GHES와 Runner 각각 DNS·라우팅을 확인합니다. 기존 Shared Key 오류에 RBAC 역할 추가만으로 해결됐다고 판단하지 않습니다.

  2. OIDC 선택 시 앱·federation 구성

    Storage 인증용 Entra 앱을 등록해 client/tenant ID를 기록합니다. GHES 사용자 SAML/SCIM 앱과 목적을 구분하고 아래 값을 입력합니다.

A1 · Storage OIDC 앱: Client ID·Tenant ID

공식 문서 원본 PNG · 확대 후 Esc로 축소
A1 · Storage OIDC 앱: Client ID·Tenant ID — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

현재 Actions Storage 인증 방식부터 확인합니다. OIDC를 사용하는 경우 Storage용 App registrations → Overview의 기존 값을 읽습니다. 신규 앱 생성은 별도 승인입니다.

② 입력 / 대조할 값 · Input

Application (client) ID와 Directory (tenant) ID를 GHES OIDC 설정과 대조합니다. App registration Object ID·service principal Object ID·Client ID를 구분합니다.

③ 확인할 결과 · Expected

사용자 SAML/SCIM 앱과 별도의 Storage 인증 앱을 정확히 식별합니다. Shared Key 방식 오류에 OIDC 앱 설정을 무조건 적용하지 않습니다.

예시 범위·주의: GitHub 공식 Azure 앱 예시이며 이름·ID는 fixture입니다. Azure 구독/Billing과 인증 테넌트는 별도 확인 대상입니다. 이 화면은 Storage IAM 권한 부여 결과가 아닙니다.

Storage OIDC 입력형식 / 조건
Issuerhttps://github.example.com/_services/token
Subjectgithub.example.com — 프로토콜 없음
Audienceapi://AzureADTokenExchange — 실제 클라우드·federation 조건과 대조
RBACStorage account scope의 해당 앱 service principal에 Storage Blob Data Owner
외부 검증 접근https://github.example.com/_services/token/.well-known/openid-configuration
https://github.example.com/_services/token/.well-known/jwks
두 주소 모두 외부 인증 서비스에서 도달 가능해야 함

A2 · Storage 앱: Federated credentials 진입

공식 문서 원본 PNG · 확대 후 Esc로 축소
A2 · Storage 앱: Federated credentials 진입 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

Storage 앱 → Certificates & secrets → Federated credentials에서 기존 신뢰를 읽습니다. 신규 또는 변경 승인 때만 Add credential을 사용합니다.

② 입력 / 대조할 값 · Input

GHES Storage issuer: https://github.example.com/_services/token. Subject: github.example.com. Audience: api://AzureADTokenExchange를 실제 구성과 대조합니다. workflow의 repo:ORG/REPO subject와 다릅니다.

③ 확인할 결과 · Expected

연합 신뢰와 외부 metadata/JWKS 도달성을 확인합니다. Storage account → Access control (IAM) → Role assignments에서 해당 SP의 Storage Blob Data Owner와 scope를 별도로 대조합니다.

예시 범위·주의: ghes-actions-test는 공식 fixture입니다. Federated credentials 탭·Add credential 진입만 보이며 펼친 입력값·완료된 신뢰·Storage IAM 역할 화면은 없습니다. 역할 추가는 별도 승인입니다.

  1. GHES Actions 연결·검사

    Management Console → Actions → Enable GitHub Actions → Azure Blob Storage Setup에서 선택한 인증 방식의 입력값을 넣습니다. OIDC는 tenant/client/account/endpoint suffix, Credentials는 승인된 connection string입니다. Test storage settings는 실제 쓰기이므로 승인 후 실행합니다.

  2. 저장·적용 완료 확인

    container 확인뿐 아니라 쓰기 성공까지 확인하고, 승인된 Save settings의 서비스 재시작 영향을 고려해 구성 완료를 기다립니다. 실패하면 Storage 오류 코드·현재 인증 모드·실제 출구 IP를 대조합니다.

다음 단계로 넘어갈 조건: Storage 연결·쓰기·구성 적용이 성공했습니다. OIDC 사용 시 외부 discovery/JWKS도 확인합니다.

STEP 10 / 12 · 선택·조건부 · 조작 전 승인 확인

10. Runner·워크플로 실행

담당
DevOps·Runner 운영자
준비값
Actions/Storage 완료·시험 저장소·runner group·label·OS
작업 위치
GHES Runner 등록 UI → 별도 Runner 호스트
  1. 별도 Runner 호스트 준비

    GHES appliance가 아닌 승인된 OS의 전용 호스트·계정을 사용합니다. GHES HTTPS·필요 Blob·공개 action/패키지 경로, 인증서 신뢰와 runner group의 허용 저장소를 준비합니다.

  2. 등록 범위·OS 선택

    조직용은 Organization → Settings → Actions → Runners → New runner에서 OS·architecture를 선택합니다. 저장소용과 조직용 URL·권한을 혼동하지 않습니다. 아래는 공식 선택 화면 예시입니다.

R1 · Self-hosted runner 추가: OS·아키텍처 선택

공식 문서 원본 PNG · 확대 후 Esc로 축소
R1 · Self-hosted runner 추가: OS·아키텍처 선택 — 공식 문서의 예제 캡처
공식 공개 문서에 수록된 실제 UI 캡처 원본을 변형 없이 내장했습니다. 합성·재구성 UI가 아니며 현재 운영 대상에서 촬영한 화면도 아닙니다. 앱명·데모 사용자·tenant/앱 ID·호스트·날짜·상태는 공식 예제 fixture이며 고객 정보가 아닙니다. 원 캡처일은 미상이고 구형 Azure AD·Preview UI가 포함될 수 있습니다. 예제 식별자를 복사하지 마세요. 공식 원문 출처
① 클릭할 위치 · Click

기존 runner·group·허용 저장소를 먼저 읽습니다. 승인된 신규 등록은 조직 Settings → Actions → Runners → New runner로 진행합니다. 저장소 범위에서는 Repository Settings → Actions → Runners → New self-hosted runner입니다.

② 입력 / 대조할 값 · Input

실제 runner 머신의 OS·아키텍처와 조직/저장소 등록 범위를 선택합니다. 예시 호스트는 https://github.example.com입니다. 등록 토큰은 ••••••••로 취급하고 문서·로그에 복사하지 않습니다.

③ 확인할 결과 · Expected

실제 GHES 화면이 제공하는 명령을 승인된 runner 머신에서 실행한 뒤 Online/Idle·허용 저장소·파일럿 job 결과를 확인합니다. 선택 화면만으로 등록 성공을 판단하지 않습니다.

예시 범위·주의: 공식 문서가 조직·저장소·enterprise 절차에 공통으로 사용하는 OS/Architecture 원본 PNG입니다. New self-hosted runner/New runner 버튼 자체·등록 토큰·완료 상태는 이 그림에 없습니다. Linux/x64 선택은 예시이며 OS 지원 범위와 실제 머신을 별도 확인합니다.

  1. 화면이 생성한 설치 명령으로 등록

    해당 GHES가 제공한 다운로드·검증·config 명령을 Runner 호스트에서 순서대로 실행합니다. 등록 토큰은 비밀이며 문서에 옮기지 않습니다. 정상 Listening/Idle을 확인하고 필요한 서비스 구성은 승인된 권한으로 수행합니다.

  2. 작은 워크플로로 왕복 검증

    Phase 9의 합성 데이터 workflow를 승인된 시험 저장소에 적용합니다. checkout → artifact upload → download → 내용 비교를 확인합니다. GHES 호환 action ref를 사용하며 GitHub.com의 artifact v4+ 예제를 무조건 가져오지 않습니다.

다음 단계로 넘어갈 조건: Runner online만이 아니라 실제 job과 artifact 왕복이 성공했습니다. 미사용이면 STEP 09와 함께 N/A로 기록합니다.

STEP 11 / 12 · 선택·조건부 · 조작 전 승인 확인

11. 선택 기능 판단

담당
서비스 책임자 + 해당 기능 운영자
준비값
추가 기능 요구·지원 버전·보안/비용 승인
작업 위치
GHES Packages·개발자 도구 및 별도 서비스 설정
  1. Packages는 독립적으로 결정

    필요한 ecosystem·registry hostname·인증·저장소를 정합니다. Actions의 Storage OIDC가 Packages에도 그대로 적용된다고 가정하지 않고 승인된 synthetic package push/pull로 검증합니다.

  2. Copilot 적용 범위 구분

    GHES 설치와 Copilot 구독·정책·외부 모델 통신은 별개입니다. 3.21 기본 절차에 3.22 CLI technical preview를 소급 적용하지 않습니다. 실제 client/provider·데이터 전송·모델 endpoint 승인을 별도로 확인합니다.

  3. 미사용 선택 기능은 명시적으로 제외

    미적용 사유·승인자를 기록하고 운영 완료 범위에 포함하지 않습니다. 필요하지 않은 서비스를 가이드에 있다는 이유로 활성화하지 않습니다.

다음 단계로 넘어갈 조건: 적용 기능별 시험 증거가 있거나 미사용/N/A와 사유가 명확합니다. 기본 GHES 완료와 구분했습니다.

STEP 12 / 12 · 기본 순서 · 조작 전 승인 확인

12. 모니터링·백업·운영 인수

담당
운영·백업·보안·지원 책임자
준비값
모든 적용 단계의 시험 결과·변경 이력·지원 경로
작업 위치
Monitor / 로그·백업·격리 복원 / 승인된 인수 기록
  1. 기본 로그·오류 대응 준비

    production.log·github-unicorn journal·nginx·audit·exceptions의 역할과 조회 권한을 정합니다. 실제 UTC 구간·노드·Target ID로 사건을 연결하고 원문 로그는 접근 제한 보관합니다.

  2. 백업·격리 복원 확인

    설치 버전에 맞는 백업 방식·전용 볼륨·보존·외부 Actions/Packages 객체 보호를 구성합니다. 운영 전 격리 복원으로 RPO/RTO와 데이터·비밀·외부 연계 분리를 확인합니다. HA를 백업으로 대신하지 않습니다.

  3. 업데이트·만료·네트워크 운영 인수

    보안 패치·공식 업그레이드 경로, 라이선스/TLS/IdP/PAT 만료, 경보 담당을 정합니다. 프록시 경유 재시험과 임시 허용 규칙 회수 결과를 남깁니다. 지원 번들 생성과 반출 승인은 분리합니다.

  4. 완료 체크리스트에 증거 연결

    구축·운영 인수 체크리스트의 각 항목에 대상·수행자 역할·승인·UTC·결과·증거 위치·잔여 담당을 기록합니다. 문서의 체크는 실제 시스템을 검사하거나 결과를 저장하지 않습니다.

다음 단계로 넘어갈 조건: 실제 PASS/FAIL/미실행/N/A가 구분되고, 복구 시험과 남은 위험을 승인한 뒤 운영 범위를 확정했습니다.

이미 구축된 환경에서 새 사용자만 추가할 때

12단계를 처음부터 다시 하지 않습니다. 아래 순서로 현재 상태를 읽고 필요한 부분만 변경합니다.

  1. 대상 앱·사용자 확정

    Cloud EMU와 GHES 앱을 분리하고 각 앱의 Tenant URL·source Object ID·할당·Scope를 확인합니다.

  2. 라이선스 조건 확인

    계약상 필요한 Cloud 소비와 GHES 설치 키 한도·만료·실사용량을 대조합니다. 여유가 없거나 갱신이 필요한 경우만 새 키를 발급·적용합니다.

  3. GHES 앱 할당·동기화

    유효한 직접 할당/보안그룹 직접 멤버를 구성합니다. 정상 Automatic job이면 다음 증분 대상이며, 승인된 즉시 처리만 사용자 한 명 온디맨드로 실행합니다.

  4. 계정·접근 확인

    새 시각의 Action/Status/Target ID → GHES active/externalId → 본인 SAML 로그인 → Org/저장소 권한을 확인합니다. 실패 시 전체 Restart나 삭제로 우회하지 않습니다.

  5. 사용량 보고·기록

    Connect를 사용하는 경우 주간 전송 또는 승인된 Sync now의 실제 수신을 확인합니다. 사용자 생성과 키 한도 변경의 증거로 사용하지 않습니다.

필요한 화면 찾기

모든 캡처는 위 해당 작업 바로 뒤에 있습니다. 아래 색인은 화면으로 바로 이동합니다. VMware·백업 등 제품/버전별 화면은 상세 장의 공식 문서와 입력표로 안내합니다.

공식 예제 화면 21개 · 작업 옆 화면 찾기
화면 / Screen단계 / Step용도 / Use
L1라이선스User licenses → Update license
L2라이선스License file 선택·업로드
S1앱 식별Entra ID → Enterprise applications
S2앱 식별All applications에서 기존 GHES 앱 찾기
S3앱 식별Overview: Application ID와 service principal Object ID
F1파일럿 할당Users and groups: 할당·Role 읽기
S4SAMLBasic SAML Configuration: GHES URL
S5SAMLAttributes & Claims: NameID와 objectidentifier
S6SAMLSAML Signing Certificate: Base64 공개 인증서
S7SAMLIdP Login URL·Identifier → GHES SAML 설정
F2SCIM 구성Provisioning: 기존 configuration 확인
S8SCIM 연결Admin Credentials: Tenant URL·Test Connection
F3SCIM 범위·매핑Properties: Scope·알림·삭제 방지
F6파일럿 프로비저닝Provision on demand: 승인된 파일럿 선택
F7파일럿 결과Perform action·View details: 실제 작업 판정
F4로그 진단Provisioning logs: 대상·시각·Action·Status
F5로그 진단Steps: 범위·매칭·대상 작업
C1사용량 보고GitHub Connect: License sync → Enable
A1Actions StorageStorage OIDC 앱: Client ID·Tenant ID
A2Actions StorageStorage 앱: Federated credentials 진입
R1Runner 등록Self-hosted runner 추가: OS·아키텍처 선택
다음은 상세 참조: 각 Phase에는 명령·오류 분기·설정 근거가 있습니다. 앞의 순서를 따라 수행하다가 해당 단계의 상세 링크를 사용하세요.

Phase 0배포 선택·용량·운영 설계

상세 참조 장 · STEP 01의 실행 순서·화면으로 돌아가기 →

담당: 아키텍트·서비스/가상화/보안 책임자선행: 업무·규제·연결 요구 수집산출물: 버전·플랫폼·사양·RPO/RTO·책임 승인서

적용 범위와 안전 원칙

공식 문서를 기준으로 일반 기업의 신규 배포·라이선스·네트워크 검증 절차를 설명한다. 실제 구성·계정·측정 결과는 승인된 환경에서 별도로 확인한다. 명령은 실행 예시일 뿐 이 문서 생성 과정에서 실행하지 않는다. github.example.com, examplerepo 및 대괄호 자리표시자는 승인된 값으로 교체한다. 기본 절차는 GHES 3.21의 VMware 단일 인스턴스이며, HA·인증·Actions는 각각 별도 승인 후 확장한다.

0-1. 제품과 운영 책임을 먼저 선택한다

선택운영·인증 경계결정 질문
GitHub Enterprise Server (GHES)기업이 가상 어플라이언스, 네트워크, 업그레이드, 백업·복구를 운영한다. GHES용 SAML·SCIM 절차를 사용한다.데이터 위치와 연결 제한을 직접 통제해야 하는가? 상시 운영 담당과 복구 예산이 있는가?
GitHub Enterprise Cloud (GHEC)GitHub가 서비스 인프라를 운영한다. 일반 사용자 계정 기반 기업 또는 EMU 기업을 선택한다.서버 운영 대신 클라우드 정책·IdP·사용량 관리에 집중할 수 있는가?
Enterprise Managed Users (EMU)GHEC의 계정 관리 방식이다. IdP가 GitHub.com 또는 GHE.com의 관리형 계정을 프로비저닝한다.계정 수명주기의 중앙 통제와 기업 외부 협업 제한이 요구사항에 맞는가?
EMU는 GHES에 설치하는 기능이 아니다

GHES의 SAML·SCIM 지원과 GHEC의 EMU는 서로 다른 제품별 구성이다. Cloud를 병용해도 계정·조직·정책이 자동 복제되지 않는다. EMU 선택 시 아래 공식 문서를 별도 절차로 이용하며, 이 가이드의 설치 선행조건으로 삼지 않는다.

공식 근거: GHES 시스템 구조 · Cloud·Server 병용 · EMU 공식 안내

0-2. 버전 기준과 지원 종료를 승인서에 적는다

기능 릴리스GA지원 종료(공식 Closing down date)본 절차의 취급
3.222026-09-082027-09-08기준일 현재 GA. RC 전용으로 분류하지 않는다. 선택 시 3.22 문서·호환성을 별도 검토한다.
3.212026-06-112027-06-11본 절차의 기준. 설치일에 지원 중인 최신 패치를 확인하고 내부 승인된 패치를 선택한다.

변경 승인서에는 실제 패치 버전, 이미지 파일명, 다운로드 날짜, 릴리스 노트의 알려진 문제, 시험 결과, 지원 종료 전 업그레이드 일정을 남긴다. 이 문서는 특정 패치 번호를 ‘최신’으로 고정하지 않는다. 문서가 열리는 것과 해당 버전이 지원 중인 것은 다르다.

공식 근거: 전체 릴리스·지원 기간 · 3.21 릴리스 노트

0-3. 지원 플랫폼별 배포 경로를 구분한다

플랫폼공식 배포 경로확인·중단 기준
VMware — 본문 주 경로공식 OVA → vSphere Deploy OVF Template → 별도 데이터 디스크 → 최초 설정3.21 문서의 ESXi 지원 범위는 5.5–8.0이다. 실제 하이퍼바이저의 공급사 지원·보안 수명도 별도 확인한다.
Azure공식 Azure 설치 가이드의 이미지·VM 배포 경로, Premium Storage 지원 메모리 최적화 VMVM SKU·리전·디스크·네트워크 요구를 Azure 문서에서 확인한다. OVA 가져오기 절차를 복사하지 않는다.
AWS공식 이미지로 EC2 인스턴스 생성, 별도 EBS 데이터 볼륨 연결AMI 리전·인스턴스 유형·EBS 성능·보안 그룹을 검토한다. VMware 디스크 설정을 그대로 적용하지 않는다.
Hyper-V공식 Hyper-V 이미지와 전용 설치 가이드3.21 문서의 Windows Server 지원 범위와 가상 디스크·VM 설정을 확인한다.
OpenStack KVM공식 QCOW2 이미지와 OpenStack 배포 절차일반 데스크톱 KVM 전체에 동일 지원을 가정하지 않는다. 이미지·볼륨·네트워크 지원 조건을 확인한다.
Google Cloud Platform공식 이미지, 지원 머신 유형, 영구 디스크 기반 배포GCP별 머신·디스크·방화벽 요구를 확인한다. VMware OVA 절차와 구분한다.

공식 근거: 지원 플랫폼 색인 · VMware · Azure · AWS · Hyper-V · OpenStack KVM · GCP

0-4. 좌석 수를 출발점으로, 실제 부하로 용량을 결정한다

공식 VMware 권장 구간x86-64 vCPU메모리루트 / 데이터IOPS
평가·데모 또는 가벼운 사용자 10명432 GB400 / 500 GB600
최대 1,000 라이선스848 GB400 / 500 GB3,000
1,000–3,000 라이선스1664 GB400 / 1,000 GB6,000

위 값은 GHES 3.21 VMware 문서의 최소 권장 구성이지 성능 보증이 아니다. Actions는 기본 CPU·메모리에 각각 최소 25%, Code Security도 각각 최소 25%의 추가 자원을 계획한다. 두 기능을 모두 쓰면 두 증가 요인을 함께 반영한다. Actions 자체의 최소 조건인 8 vCPU / 64 GB도 동시에 충족해야 하므로 단순히 표에 25%만 더해 끝내지 않는다.

CPU 증설 시에는 16 vCPU까지 vCPU당 최소 6.5 GB 메모리 추가를 권장한다. 이는 증설 지침이며 위 표 전체를 대체하는 전역 최소 비율이 아니다. 예를 들어 12 vCPU / 80 GB는 검증을 시작할 계획안일 뿐, 사용자 50명 또는 특정 runner 수용량을 보증하지 않는다. runner 연결 수·동시 job·job 길이·artifact 크기·Git 부하는 서로 다른 지표이다. runner는 어플라이언스와 분리된 실행 호스트에 둔다.

  1. 부하 목록 수집

    저장소 수·대형 저장소 크기·LFS 증가량·동시 clone/fetch·API/webhook 빈도·Code Security 분석·Actions job 및 artifact/cache 보존량을 적는다. 반복 polling은 줄이고 webhook 기반 연계를 검토한다.

  2. 스토리지 설계

    SSD의 지연시간·지속 IOPS·동시 부하 여유를 확인한다. 기본 루트 디스크는 200 GB이므로 비클러스터 신규 배포는 400 GB로 사전 조정한다. 약 절반은 업그레이드·롤백용이어서 400 GB 전체가 루트 파일시스템에 표시되지 않는다.

  3. 데이터 볼륨 분리

    루트와 별도로 새 빈 데이터 디스크를 전원 투입 전에 연결한다. 기존 데이터나 파티션이 있는 디스크를 재사용하지 않는다. VMware는 thick provisioning with lazy zeroing을 권장한다. 데이터 디스크 초기화·포맷 명령을 수동 실행하지 않는다.

  4. 파일럿으로 수정

    업무를 대표하는 시험 저장소 examplerepo와 승인된 부하로 clone·push·API 지연, CPU·메모리 압박, 디스크 지연·여유, 백업 시간을 측정한다. 목표·경보 임계값을 사전에 합의하고 초과하면 확장 후 재시험한다. 좌석 수만으로 운영 승인하지 않는다.

공식 근거: VMware 하드웨어·디스크 · Actions 최소 자원·외부 저장소

0-5. 운영 인수인계 워크시트

결정 항목작성할 값조회 / 변경 책임과 증거
서비스·복구업무 시간, RPO [허용 데이터 손실 시간], RTO [복구 완료 목표 시간], 보존 기간, 복구 우선순위서비스 책임자가 승인하고 백업 담당자가 복구 시험으로 검증. HA는 백업을 대체하지 않는다.
인프라VM 사양·데이터스토어·분리 데이터 디스크·확장 여유·장애 도메인관제 담당은 조회, 가상화 담당은 승인된 변경 창에서만 변경.
DNS·NTP·TLSFQDN, resolver, NTP, SAN, 인증서 체인·만료일·갱신 일정네트워크·PKI 책임자를 각각 지정. 개인키 보관자와 업로드 수행자를 구분.
특권 접근웹 enterprise owner, Console root/운영자, SSH 공개키 소유자, 비상 접근 경로전담 운영 주·부 담당자 지정. 일반 관제 계정에 SSH 전체 권한을 주지 않고 자격증명은 비밀 저장소에 보관.
변경·지원요청자, 승인자, 수행자, 검증자, 중단 조건, 지원 연락 경로조회 기록과 변경 이력을 분리. 실패 시 설정 재저장·재부팅을 반복하지 않고 증거를 보존.
일반 Linux 서버가 아니다

GHES는 x86-64 가상 어플라이언스다. ARM VM, 임의 OS 위 apt/npm 설치, 내부 애플리케이션 파일 수정, 어플라이언스에 runner·백신 에이전트 등 임의 소프트웨어 추가를 기본 절차로 삼지 않는다. 공식 지원 범위 밖 작업은 GitHub Support에 사전 확인한다.

공식 근거: 시스템·백업 구조 · 관리 셸 지원 범위

진행 기준 / 완료 증거: 지원 버전과 제품 선택, 부하 파일럿 계획, 디스크·인증서·전담 운영 책임이 승인되어야 한다.

Phase 1계약 모델·라이선스 확보와 검증

상세 참조 장 · STEP 02의 실행 순서·화면으로 돌아가기 →

담당: 구매·Cloud billing·GHES 운영 담당선행: Phase 0 제품 선택산출물: 라이선스 파일·한도/사용량 대조표·갱신 책임

1-1. 계약 모델부터 판별한다

경로발급·좌석 기준선행조건 / 담당
독립형 유료·Volume/SubscriptionSales가 계약을 설정하고 구매 좌석·계약 기간에 맞는 서버 파일 제공. Cloud·Server 병용 권리를 포함한다.구매·라이선스 담당이 계약과 파일 수령 경로 확인. 모든 경우에 Cloud 기업을 먼저 만들 필요는 없다.
GHES 평가판승인된 trial 파일의 기간·제한을 확인한다. 운영용 계약과 혼동하지 않는다.공식 Enterprise 사이트의 평가·다운로드 경로. Cloud 생성이 보편적인 필수조건은 아니다.
PAYG / MeteredCloud-first. 사용자를 먼저 Cloud 조직에 할당하고, 키 생성 시점의 consumed Cloud licenses를 서버 좌석 기준으로 사용. 생성 키 유효기간은 1년.Cloud 기업·조직·청구 권한 준비. 공식 병용 표는 GHES 3.13+ 및 GitHub Connect를 명시한다.
서버만 사용하는 PAYG 사용자의 처리

공식 문서는 Server-only 사용자가 이메일 중복 제거 후 metered 청구에 추가된다고 설명한다. 그러나 서버 키의 설치 한도는 생성 당시 Cloud 소비 좌석에 묶인다. 이 설명을 ‘서버 전용 인원만으로 원하는 키를 셀프서비스 발급할 수 있다’로 해석하지 않는다. Cloud 조직 할당 없이 서버 전용으로 시작하거나 한도가 부족한 계약은 Sales·Billing Support에 발급·청구 경로를 확인한다.

공식 근거: 라이선스 파일 · PAYG·Volume 병용 비교

1-2. 사람 수, Cloud 소비, 설치된 서버 한도를 분리한다

Cloud People > Members의 전체 수나 Total consumed 값을 키 좌석 산정에 대신 쓰지 않는다. Billing and licensing > Licensing의 consumed Cloud licenses를 확인한다. GHEC 계정·SCIM 계정 생성만으로 Enterprise 유료 좌석 소비가 확정되지 않는다. 조직에 속하지 않은 unaffiliated 사용자, Copilot만 배정된 인원 수도 GHE 소비 좌석 수와 같지 않다. 조직 소속·협업자 역할·구독 유형 등 공식 과금 조건을 확인하고 특히 Visual Studio 결합 라이선스의 예외도 별도 검토한다.

  1. 현재 값 기록

    계약 모델, Cloud 소비 좌석, 설치된 GHES 키 한도, GHES 실제 사용 좌석, 만료일을 서로 다른 열로 적는다. PAYG 생성 전 조직 할당이 완료되고 Licensing 화면의 소비에 반영됐는지 확인한다.

  2. 좌석 확대

    설치 한도 확대가 필요하면 PAYG는 Cloud 소비 증가를 확인한 뒤 새 서버 키를 생성·다운로드하고 GHES에 직접 업로드한다. Cloud 인원 증가만으로 기존 서버 키 한도가 자동 확대되지 않는다. Volume은 추가 구매 후 제공된 파일을 적용한다.

  3. Connect의 경계 확인

    라이선스 동기화는 GHES → Cloud 사용량 보고 및 이메일 기반 중복 제거다. 계정 프로비저닝이나 Cloud → GHES 키·quota 자동 갱신이 아니다. 자동 보고는 매주 실행되며 Sync now도 사용량만 전송한다. 한도·만료일을 바꾸는 작업과 분리한다.

  4. 만료 대응

    만료일·내부 갱신 담당·알림 시점을 기록하고 갱신 파일 업로드 후 재검증한다. 키 만료 시 웹·Git 접근을 사용할 수 없으므로 정상 업무 중단 전에 처리한다. 회사명·키 원문·사용자 이메일이 담긴 출력은 공개 문서에 붙이지 않는다.

공식 근거: Cloud 소비 사용자·예외 · 사용량 동기화 방향

1-3. 다운로드와 업로드 절차

  1. Cloud 경로

    승인된 기업 소유자 권한으로 GitHub Enterprise Cloud에 접속한다. 프로필 → Enterprise 또는 Enterprises → 대상 기업 → Billing and licensing → Licensing으로 이동한다. consumed Cloud licenses 증가 또는 만료까지 30일 이하일 때 표시되는 노란 배너의 Generate new license를 선택한다. Enterprise Server licenses → Download로 파일을 받는다. 올바른 기업인지, 파일 생성일·수량이 요청과 일치하는지 대조한다.

  2. 독립형·평가 경로

    Cloud 기업이 없는 경우, 평가판, GHE.com Volume 또는 경로가 불명확한 경우 공식 enterprise.github.com/download에서 계약 권한으로 확인한다. 파일이 없으면 구매·Sales에 문의한다. 단순히 Cloud 계정부터 새로 만드는 것으로 해결하지 않는다.

  3. 안전한 보관

    파일의 계약·만료일·좌석을 확인하고 접근 제한 저장소에 보관한다. 다운로드 권한과 GHES 업로드 권한을 분리한다. 이메일 본문, 저장소, 실행 명령 인자에 라이선스 원문을 넣지 않는다.

  4. 신규 설치

    Phase 3에서 격리된 최초 설정 화면에 파일을 업로드하고 root Management Console 암호를 설정한다. 아직 생성되지 않은 웹 사용자나 IdP 계정 암호를 입력하는 단계가 아니다.

  5. 기존 인스턴스 갱신

    웹 site administrator로 로그인 → Enterprise settings → Settings → License → User licenses / Quick links → Update license. Console 인증이 요구되면 별도 Console 자격증명을 사용한다. License file 선택 → Upload. 백그라운드 반영에 몇 분 걸릴 수 있으므로 완료 후 한도·만료일을 다시 확인한다.

Console 사용자명을 혼동하지 않는다

Console의 Root site admin 경로는 최초 설정에서 정한 암호로 인증한다. 별도 Management Console user를 만든 경우 해당 Console 사용자명·자격증명을 쓴다. 웹 enterprise owner의 로그인명, SAML 로그인, SSH의 고정 사용자명 admin을 Console 사용자명으로 대입하지 않는다.

공식 근거: 공식 다운로드 분기·UI · 업로드 UI · Console 인증 · Console 계정 유형

1-4. 설치 후 조회로 파일·사용량을 각각 검증한다

조회 · Phase 3 이후, 승인된 GHES 관리 SSH 셸 · bash
ghe-license info
ghe-license check
판정: info는 설치 키의 seats·unlimited_seating·expire_at 등을 보여준다. check는 유효한 키라면 License is valid.를 반환한다. 출력은 실제 값이며 예시 좌석 수를 정답으로 기대하지 않는다.

ghe-license info의 seats는 실제 사용 인원이 아니라 키 한도다. seats: 0이고 unlimited_seating: true이면 무제한 의미이지 사용자가 0명이라는 뜻이 아니다. 사용량은 License UI 또는 다음 REST 조회의 seats_used와 구분한다.

조회 · gh가 이미 설치되고 대상 GHES의 승인된 인증이 설정된 관리자 PC · bash
gh api --hostname github.example.com --method GET /enterprise/settings/license
판정: GHES REST API의 HTTP 200과 seats, seats_used, seats_available, kind, expire_at, days_until_expiration을 확인한다. 인증·권한 오류는 별도 해결하며 이 예시는 토큰 생성이나 scope 변경을 하지 않는다.
실패·차이확인 순서중단·해결
파일을 찾지 못함 / 생성 메뉴 없음계약 모델 → Cloud 기업 선택 → 권한 → Licensing 소비 수임의 기업·조직을 추가하지 말고 구매 담당과 Sales에 확인.
업로드 후 좌석이 그대로다운로드한 파일의 생성 시점 → 실제 업로드 → 반영 대기 → 키 infoConnect 동기화로 한도를 늘리려 하지 말고 올바른 파일 재발급 여부 확인.
REST 401/403/404대상 hostname → 기존 승인 인증 → 사용자 역할 → 해당 버전 endpoint권한 부족을 광범위 토큰 발급으로 우회하지 않는다. 접근 정책에 맞춰 담당자에게 요청.
invalid / expired계약 기간·파일·시간 동기화 확인사용자 온보딩 중단, 갱신·지원 요청 후 유효성 재검증.

공식 근거: ghe-license info / check · 라이선스 GET API

1-5. 신규 사용자마다 키를 바꾸기 전에 판단한다

판단다음 작업완료 증거
설치 키가 유효하고 추가 인원을 수용할 잔여 좌석이 충분함사용자마다 키를 교체하지 않는다. 승인된 IAM·조직 할당 절차로 진행한다.설치 seats·만료일과 seats_used / seats_available, 추가 예정 인원 대조.
한도 확대 또는 만료 갱신이 필요함계약 경로에 맞는 새 .ghl을 발급받아 승인 후 직접 업로드한다. Sync now로 해결하지 않는다.대상 기업·계약, 파일 생성일·수량·만료일 및 적용 후 설치 값 일치.
Cloud 소비 수·파일 수량이 예상과 다름PAYG 키는 생성 시점 consumed Cloud licenses의 스냅샷이다. People 전체 수·Total consumed·Copilot·unaffiliated 수로 대체 계산하지 않는다.실제 조직 할당·과금 조건·Licensing 반영 확인. 불일치가 남으면 Billing Support·Sales 확인 전 중단.

공식 근거: 파일·PAYG 좌석 기준 · 다운로드·노란 배너

1-6. 후보 파일 검사·UI 우회·전후 증거를 남긴다

  1. 변경 전 증거·복구 준비

    변경 승인 번호·수행자·검증자·변경 창과 현재 기업·Cloud 소비·설치 한도·사용량·만료일·조회 시각을 기록한다. 기존 .ghl은 접근 제한 저장소에 보존하고 덮어쓰지 않는다. 이전 키가 만료됐거나 현재 사용량을 수용하지 못하면 되돌리기도 안전하지 않으므로 복구 가능 여부와 Support 연락 기준을 먼저 승인받는다.

  2. 후보 파일만 조회

    승인된 전달 경로로 관리 셸에서 읽을 수 있는 제한된 위치에 새 .ghl을 준비한 뒤 아래 명령을 사용한다. /APPROVED/PATH/new-license.ghl은 실제 승인 경로로 바꾼다. 생성일은 다운로드 기록과 함께 대조한다. 이 검사는 설치 키를 교체하지 않으며 check 성공만으로 올바른 기업·수량을 보증하지 않는다.

조회 · 승인된 GHES 관리 SSH 셸; 접근 제한된 후보 파일만 검사 · bash
GHE_LICENSE_FILE=/APPROVED/PATH/new-license.ghl ghe-license info
GHE_LICENSE_FILE=/APPROVED/PATH/new-license.ghl ghe-license check
판정: 후보 파일의 seats·unlimited_seating·expire_at과 유효성을 승인 요청에 대조한다. 환경변수는 각 조회 명령에만 적용된다. 회사명·파일 원문은 공개 기록에 남기지 않는다.
  1. License 화면이 HTTP 500이면

    오류 시각·대상 화면·요청 ID를 보존하고 승인된 관리망에서 https://github.example.com/setup으로 Management Console에 진입한다. 별도 Console 자격증명과 TCP 8443 접근을 확인하고 실제 Console UI의 라이선스 업로드 화면을 사용한다. Console까지 실패하면 반복 업로드·재부팅 대신 오류 증거를 가지고 Support에 문의한다.

  2. 승인된 업로드·반영 대기

    1-3의 License file → Upload로 후보 파일을 올린다. 백그라운드 반영은 몇 분 걸릴 수 있으나 고정 SLA가 아니다. 완료 상태를 확인하고 중복 업로드를 피한다. 전체 OS 재부팅은 공식 업로드 절차의 필수 단계로 문서화되어 있지 않으며 개별 재부팅 경험을 일반 요구사항으로 삼지 않는다. CLI의 --apply는 영향을 받는 서비스를 재시작하므로 별도 변경 승인이 필요하다. 추측한 import 구문이나 구성 적용 명령을 기본 후속 작업으로 실행하지 않는다.

  3. 변경 후 비교·종료

    1-4의 환경변수 없는 ghe-license info·ghe-license check로 설치 키를 다시 조회하고 License UI/REST의 한도·사용량·만료일, 웹·Git 서비스 복귀를 기록한다. 변경 전·후 값과 업로드 완료 시각을 한 표에 남긴다. 불일치·오류는 파일/적용/사용량을 분리해 조사하고 승인·유효성 확인 없이 이전 파일로 되돌리지 않는다. Connect 보고와 사용자 생성 성공은 별도 검증한다.

공식 근거: 업로드·백그라운드 반영 · 후보 파일 조회·서비스 재시작 · Console 직접 접근

진행 기준 / 완료 증거: 설치 전 올바른 계약 파일을 확보한다. 설치 후 키 유효성·만료일·한도와 실제 사용량을 분리 검증한다. 미확정 PAYG 서버 전용 경로는 Sales 확인 전 진행하지 않는다.

Phase 2통신 방향·DNS·TLS와 검증 설계

상세 참조 장 · STEP 03의 실행 순서·화면으로 돌아가기 →

담당: 네트워크·PKI·IAM·GHES 운영 담당선행: FQDN·토폴로지·기능 선택산출물: 방화벽 행렬·DNS/TLS·Cloud 경로 증거

2-1. 연결을 시작하는 주체별로 방화벽을 설계한다

아래 포트는 모두 GHES 인바운드로 개방하는 목록이 아니다. 출발지·목적지·프로토콜·반환 트래픽·프록시 경로·업무 용도를 변경 요청서에 적는다. 실제 도입한 기능만 승인하고 관리망은 사용자망과 분리한다.

네트워크: 출발지와 목적지를 분리해 승인 동일한 로컬 Excalidraw 도형 데이터로 생성한 설명용 SVG. 편집기 내보내기가 아니며 HTML의 Clawpilot 테마를 상속합니다. 네트워크: 출발지와 목적지를 분리해 승인 화살표는 연결 개시 방향 · 443은 HTTPS · 운영 포트는 인터넷 공개 대상이 아님 인바운드 · 사용자 사용자 PC 브라우저 / Git HTTPS GHES 앱 / Git HTTPS 443 인바운드 · 프로비저닝 Entra SCIM 서비스 승인된 대상 범위 GHES SCIM API /api/v3/scim/v2 승인된 경계 경로 프록시 / 방화벽 443 443 아웃바운드 · 보고 GHES Connect 사용량 보고 GHEC 계약별 보고·청구 443 아웃바운드 · 저장소 GHES / 전용 Runner Runner 경로는 조건부 외부 Blob Storage Actions 객체 443 SSO는 PC 브라우저 ↔ Entra 인증 후 GHES로 복귀하는 별도 흐름 OIDC 저장소 선택 시 추가: 인증 서비스 → GHES 443 · 공개 OIDC discovery / JWKS (SCIM과 별개) 122 관리 SSH · 8443 관리 콘솔: 승인된 관리자 PC의 사설 경로만 허용 · Git SSH는 별도 22 경로 설명용 개념도 · 실제 화면이나 고객 환경이 아님 · 연결은 주요 논리 흐름만 표시
설명용 개념도. 경로별 통신 방향. 관리 PC 접속, 브라우저 SSO, Entra SCIM, Connect 및 Actions Storage 연결은 서로 다른 증거가 필요합니다.
시작 주체 → 목적지포트 / 조건허용 범위·검증
사용자 PC → GHESTCP 443 / Git SSH는 TCP 22웹·HTTPS Git과 SSH Git을 구분. 22는 관리 셸이 아니다. 80은 승인한 HTTP→HTTPS 전환 용도일 때만.
관리자·점프 호스트 → GHESTCP 8443 / TCP 122Console / 관리 SSH. 지정 운영망만 허용하고 일반 사용자·인터넷 전체에는 개방하지 않는다.
사용자 브라우저 ↔ GHES·IdP각 HTTPS TCP 443SAML 브라우저 리디렉션·응답 경로. PC의 SSO 성공은 IdP 서버의 SCIM 연결 성공을 의미하지 않는다.
Entra 프로비저닝 서비스 → GHES SCIMTCP 443 / Cloud 직접 연결 구성일 때외부에서 해석·도달 가능한 DNS, NAT 또는 LB/WAF 게시 경로, 신뢰 가능한 TLS 필요. 사설 IP에 443만 열어서는 부족.
GHES → GHEC / GitHub Connect이 절차는 HTTPS TCP 443 사용; 공식 설명은 TLS 연결의 443 또는 80GitHub.com 대상은 github.com, api.github.com, uploads.github.com 세 호스트를 승인한다. 평문 HTTP 허용으로 해석하지 않는다. GHE.com은 별도 공식 목적지를 확인하며 인바운드 관리 포트를 열지 않는다.
runner → GHES·API·Actions/artifact 호스트TCP 443실제 GHES FQDN·API 하위 도메인·반환된 다운로드 호스트를 확인. cache 및 직접 전달되는 artifact는 runner → Blob 경로도 필요.
GHES → Azure Blob / 인증 서비스TCP 443 / Blob 선택 시실제 승인된 Blob endpoint를 허용한다. login.microsoftonline.com은 저장소 OIDC 인증을 선택한 경우에 포함한다. 직접 연결·Private Endpoint별 DNS와 경로를 검증하며 GHES 성공만으로 runner 다운로드를 판정하지 않는다.
클라우드 OIDC 검증 서비스 → GHESTCP 443 / OIDC 외부 저장소 인증 시공개 discovery·JWKS URL에 접근 필요. Blob 데이터 트래픽 방향과 반대인 인증 경로를 별도 심사.
GHES → 지정 DNS / NTPDNS UDP·TCP 53 / NTP UDP 123승인 resolver·시각 서버만 목적지로 지정. 모든 클라이언트에서 GHES로 53·123을 여는 규칙이 아니다.
GHES → SMTP 릴레이설정한 SMTP 포트·TLS 방식메일 발송용 아웃바운드. 인바운드 메일 회신 기능의 TCP 25는 선택 기능으로 별도 검토.
HA 노드 상호 간TCP 122 및 UDP 1194HA 구성의 모든 노드 사이에 필요한 양방향 연결. 인터넷·전체 사내 대역으로 확장하지 않는다.
GHES 및 runner → GitHub.com (각 경로 별도)TCP 443 / 공개 Actions 자동 접근을 켠 경우양쪽 아웃바운드가 필요하다. runner의 github.com, api.github.com, codeload.github.com 등 공식 요구를 검토. Connect 세 호스트가 모든 workflow 의존성을 포함하지 않으며 작업별 외부 패키지·레지스트리는 별도 승인.

공식 근거: 공식 포트·HA·Connect · Connect 연결 경계 · runner 통신 · Blob·OIDC 선행조건 · GHES SCIM 도달성

2-2. DNS·게시·인증서의 책임 경계를 고정한다

  1. FQDN 확정

    github.example.com과 내부·외부 DNS 응답, VIP/NAT, TTL, 갱신 담당을 승인한다. GHES 내부 resolver에서도 자신의 이름이 해석되어야 한다. 초기 설정 후 hostname 변경은 장애·보안키 무효화 가능성이 있으므로 단순 DNS 변경 작업으로 취급하지 않는다. 필요 시 공식 신규 인스턴스·복원 경로 및 Support를 검토한다.

  2. 하위 도메인 격리

    *.github.example.com wildcard DNS 또는 공식 목록의 개별 레코드를 만든다. assets, avatars, codeload, raw, uploads, media, gist, pages 등 사용할 서비스가 같은 승인된 게시 경로로 해석되는지 확인한다. API·Actions에 필요한 이름도 해당 기능 문서와 함께 확인한다. 격리 후 이전 /raw/ 같은 경로의 404를 전체 서비스 장애로 오판하지 않는다.

  3. TLS 준비

    SAN에 github.example.com과 *.github.example.com을 포함한다. wildcard만으로 루트 FQDN은 보호되지 않는다. GHES 업로드용 인증서·중간 체인은 PEM, 개인키는 암호 없는 RSA PEM으로 준비하고 개인키 보관자를 지정한다. 내부 CA는 승인된 PC·runner의 신뢰 저장소에 배포하되 Cloud SCIM 클라이언트도 그 체인을 신뢰한다고 가정하지 않는다.

  4. LB/WAF 확인

    클라이언트 → LB에서 TLS를 종료해도 LB → GHES는 HTTPS를 유지한다. HTTP 다운그레이드는 지원되지 않는다. FQDN·SNI·인증서 검증·SCIM 경로·HTTP 메서드·Authorization 헤더가 정상 전달되는지 확인한다. WAF의 브라우저 인증 챌린지나 로그인 HTML 응답을 SCIM API 앞에 두지 않는다.

  5. NTP·인증서 수명

    승인 NTP primary·secondary를 지정하고 UDP 123 반환 경로를 확인한다. 하이퍼바이저 시각 강제 설정과 GHES NTP가 충돌하지 않게 한다. TLS 갱신은 발급→키 전달→업로드→변경 창→전체 체인·SAN 재검증으로 운영하고 만료 경보·주/부 담당을 둔다.

Entra 출발지 허용 목록은 최신 공식 값으로 관리

Microsoft Learn의 IP Ranges 절은 AzureActiveDirectory 서비스 태그를 안내한다. 사용 중인 Cloud에 맞는 최신 공식 IP 범위 파일/API, 검토 날짜, 갱신 책임자를 기록한다. 이 문서에 고정 IP를 복사하거나 모든 Azure·인터넷 IP를 일괄 허용하지 않는다. 일반 온프레미스 SCIM provisioning agent는 별도 애플리케이션 통합 방식이다. GHES 갤러리 앱에 에이전트를 붙이면 자동으로 동일 지원을 받는 대체 경로라고 가정하지 말고 양쪽 지원·매핑·인증 방식을 검증한다.

외부 저장소 OIDC를 선택하면 https://github.example.com/_services/token/.well-known/openid-configuration과 https://github.example.com/_services/token/.well-known/jwks의 공개 도달성을 별도 승인한다. 완전 사설망 정책과 양립하지 않으면 무작정 전체 사이트를 공개하지 말고 인증 방식과 배포 설계를 다시 결정한다.

공식 근거: hostname 변경 경고 · DNS resolver · 하위 도메인·SAN · TLS·LB 제한 · NTP · Entra IP Ranges

2-3. PC 검사와 Cloud 검사 결과를 분리한다

조회 · 승인된 Windows 사용자 PC / 마지막 두 항목은 관리자 PC · powershell
Resolve-DnsName github.example.com
Resolve-DnsName assets.github.example.com
Test-NetConnection github.example.com -Port 443
# 아래 두 항목은 승인된 관리망 PC에서만 확인
Test-NetConnection github.example.com -Port 8443
Test-NetConnection github.example.com -Port 122
판정: DNS가 승인된 주소로 해석되고 필요한 포트의 TcpTestSucceeded가 True여야 한다. 이는 해당 PC 경로만 입증하며 TLS·Entra SCIM·OIDC 검증 서비스의 도달성을 입증하지 않는다.
조회 · OpenSSL 3.x와 승인 CA 신뢰가 준비된 관리자 PC · bash
openssl version
openssl s_client -connect github.example.com:443 \
  -servername github.example.com -verify_hostname github.example.com \
  -verify_return_error -showcerts </dev/null
curl -q --proto '=https' --connect-timeout 10 --max-time 30 \
  --silent --show-error --dump-header - --output /dev/null \
  https://github.example.com/
판정: OpenSSL 3.x인지 확인 후 SNI·hostname·체인 검증 성공 및 Verify return code: 0을 확인한다. curl -q는 사용자 curl 설정을 읽지 않으며 리디렉션을 자동 추적하지 않는다. 200 또는 설계한 30x의 Location을 검토하고 TLS 오류·다른 호스트 이동이면 중단한다.

동일 검사를 assets 등 실제 사용하는 하위 도메인에도 반복한다. 내부 CA라면 승인된 CA 번들을 사용하도록 도구를 구성한다. -k로 검증을 끄거나 -L로 잘못된 리디렉션을 숨기지 않는다. 401/403은 HTTP 서버 도달의 단서일 뿐, 인증·권한·SCIM 동작 성공은 아니다.

증상우선 분리할 원인검증 증거
DNS는 되지만 TCP timeout라우팅·NAT·보안 그룹·방화벽·LB health같은 시각의 출발지와 경계 장비 허용/차단 로그.
TLS 이름·체인 오류SAN·SNI·중간 인증서·프록시 TLS 검사·클라이언트 trust검증한 이름, 만료일, 체인 결과. 개인키는 수집하지 않는다.
PC 성공 / Entra 실패공개 DNS·Cloud 출발지·WAF 정책·Cloud가 신뢰하지 않는 CAEntra Test Connection 시각·오류와 LB/GHES 요청 수신 로그 비교.
SCIM 401/403/404 또는 HTML토큰·권한·SCIM 활성화·endpoint·리디렉션·WAF 챌린지IAM 담당이 endpoint와 인증을 확인. 네트워크 전체 허용으로 해결하지 않는다.
등록된 runner에서 cache 실패runner → Blob 직접 연결·DNS·프록시·스토리지 권한GHES → Blob 성공과 별개로 runner의 실제 다운로드 endpoint·오류 확인.
  1. 설치 전 설계 게이트

    방화벽 규칙과 DNS·TLS 발급·NTP·외부 게시 책임을 승인한다. 아직 기동하지 않은 GHES의 연결 성공을 요구하지 말고 Phase 3 이후 실행 검증 항목을 미완료로 남긴다.

  2. 네 가지 증거 수집

    기동 후 ① 각 실제 호출 경로의 DNS 결과 ② FQDN·체인 포함 TLS 성공 ③ IAM 설정 후 Entra의 실제 Test Connection 결과 ④ 동일 시각의 LB/WAF 및 GHES 요청 수신·응답 상관관계를 모은다. 시각·경로·상태코드·요청 ID를 기록하고 토큰·개인정보는 가린다.

  3. 제한된 파일럿

    네 가지 증거가 확보된 후 소수의 승인된 사용자로 SSO와 프로비저닝을 검증한다. Test Connection은 사용자 생성·수정·중지를 모두 시험하는 기능이 아니므로 실제 수명주기는 SCIM 단계에서 확인한다. 대기 시간이 0이거나 항상 40분 이내라는 SLA를 약속하지 않는다.

공식 근거: SCIM 선행조건·계정 · Entra Test Connection·주기·온디맨드

2-4. 임시 아웃바운드 허용을 승인된 프록시 경로로 전환한다

임시 전체 허용은 운영 완료가 아니다

외부 연결 차단을 진단하려고 프록시 없이 넓은 아웃바운드를 임시 허용했더라도 운영 최종 상태로 승인된 것은 아니다. 프록시 전환·재시험이 남아 있으면 미완료로 기록한다. 이 절차는 새 광범위 허용을 권장하지 않는다.

  1. 현재 규칙 고정·승인

    기존 규칙 ID·출발지·목적지·포트·직접/프록시 경로·만료 시각·담당자·승인자를 적고 네트워크 로그로 실제 외부 NAT IP를 확인한다. GHES 사설 IP나 관리자 PC 공인 IP로 대신하지 않는다. 변경 창·중단 기준·승인된 복구 경로를 정한다.

  2. 승인된 HTTP 프록시 구성

    Management Console의 HTTP Proxy Server와 HTTP Proxy Exclusion에서 승인 URL·포트와 꼭 필요한 예외만 검토한다. GHES → 프록시 경로와 프록시 → 외부 목적지 경로를 따로 승인한다. Actions 사용 시 HTTP 프록시만 지원되며 HTTPS/SOCKS5 프록시는 지원되지 않는다. HTTP 프록시를 쓰더라도 목적지 HTTPS/TLS 검증은 유지한다. Privacy/Private mode 변경은 공개 범위에 영향을 주므로 별도 보안 검토 없이 해제하지 않는다. 승인된 설정 저장은 서비스 재시작·중단 가능성을 고려하고 구성 완료를 기다린다.

  3. Connect 세 목적지·Cloud 허용 목록

    github.com, api.github.com, uploads.github.com의 TCP 443을 프록시 경유로 허용한다. GHES 서비스가 실제 쓰는 경로와 프록시 예외를 확인하고 전환 후 외부 NAT IP를 기록한다. Cloud 기업에 IP allowlist가 있으면 이 실제 출구 IP/대역을 승인받아 반영한다. 임의 IP 확인 사이트로 조회하지 말고 경계 장비·프록시 로그를 사용한다.

  4. 경로 시험과 기능 시험 분리

    2-5의 제한된 무인증 검사를 수행하고 서비스 요청의 같은 시각 로그로 프록시 통과를 대조한다. 이어 실제 GitHub Connect 사용량 동기화 결과·최근 성공 시각·Cloud 수신 값을 확인한다. 별도로 승인된 파일럿 사용자의 SCIM 생성·조직 할당·로그인을 확인한다. 동기화 성공은 계정 생성이나 설치 키 확대의 증거가 아니다.

  5. 임시 규칙 회수·재시험

    승인된 프록시 경로의 성공 증거와 복구 계획을 검토한 뒤 변경 창에서 임시 광범위 규칙을 제거한다. 제거 후 같은 Connect·프로비저닝·필요한 Actions 검사를 다시 수행해 우회 경로 의존이 없음을 확인한다. 실패하면 증거를 보존하고 사전 승인된 복구 절차를 적용하며 무기한 전체 허용으로 돌아가지 않는다.

Blob은 실제 저장소 endpoint의 TCP 443, 저장소 OIDC를 선택한 경우에만 login.microsoftonline.com을 추가한다. 직접 연결 또는 Private Endpoint에 맞는 DNS 응답·라우팅·프록시 예외를 GHES와 runner 각각 확인한다. 지정 DNS의 UDP/TCP 53과 NTP의 UDP 123은 HTTPS 프록시와 별도 경로다. runner 프록시·출구 IP는 GHES와 같다고 가정하지 않으며 공개 Actions·패키지·레지스트리 의존성도 별도 시험한다.

공식 근거: Connect의 세 호스트·Cloud IP allowlist · 아웃바운드 프록시·Actions 제한 · Azure Blob·OIDC

2-5. GHES에서 세 목적지만 제한적으로 검사한다

승인된 GHES 관리 셸에서 서비스와 같은 프록시·DNS·CA 신뢰·예외 경로인지 먼저 확인한다. Console 설정이 셸 curl에 자동 반영된다고 가정하지 않는다. 불일치하면 네트워크 담당이 승인된 시험 경로를 준비한 뒤 실행한다. 토큰·Authorization·쿠키를 추가하지 않고 환경변수 전체나 프록시 자격증명을 덤프하지 않는다. PC에서 수집한 성공 로그만으로 GHES 서비스 경로를 입증할 수 없다.

조회 · 승인된 GHES 관리 SSH 셸; 서비스와 동일 경로임을 확인한 후 · bash
date -u '+%Y-%m-%dT%H:%M:%SZ'
for url in https://github.com/ https://api.github.com/meta https://uploads.github.com/; do
  printf '\nURL=%s\n' "$url"
  rc=0
  curl -q --proto '=https' --connect-timeout 10 --max-time 30 \
    --silent --show-error --output /dev/null \
    --write-out 'http=%{http_code} proxy_connect=%{http_connect} peer=%{remote_ip} tls_verify=%{ssl_verify_result} seconds=%{time_total}\n' \
    "$url" || rc=$?
  printf 'curl_exit=%s\n' "$rc"
done
판정: 세 URL을 각 한 번, 연결 10초·전체 30초 제한으로 검사한다. 재시도·인증·리디렉션 추적·TLS 검증 해제를 하지 않는다. peer는 연결 상대(프록시일 수 있음)이지 실제 외부 NAT IP의 증거가 아니다.
관찰판정·다음 확인
curl exit 6 / 7 / 28 / 60각각 목적지 DNS 해석 실패 / 연결 실패 / 시간 초과 / 인증서 검증 실패. 프록시 이름 해석 실패는 exit 5일 수 있다. 같은 시각의 DNS·방화벽·프록시·CA 로그와 대조한다.
curl exit 0 + HTTP 2xx/3xx전송 성공 단서이며 Connect 인증·사용량 보고 성공은 아니다. 3xx는 추적하지 않았으므로 승인된 응답 경로인지 확인한다.
HTTP 4xx 또는 proxy_connect 오류uploads 루트 등의 4xx 자체를 네트워크 단절로 단정하지 않는다. 원본 서버 응답인지 프록시 차단 응답인지 구분한다. 407은 프록시 인증, 403은 원본·프록시 모두 가능하다. 상태코드·시각·요청 ID와 프록시/서비스 로그로 판별한다.
라이선스 관련 HTTP 400원본 서버의 라이선스 오류 응답이 확인됐다면 네트워크 timeout과 다르다. 파일·설치 한도·사용량을 P1에서 확인한다. 이 무인증 검사만으로 라이선스 오류를 재현·진단하지 않는다.

이 검사는 HTTP 오류에도 curl exit 0이 나올 수 있으므로 HTTP 상태와 종료 코드를 함께 읽는다. 출력은 승인된 제한 기록에 시각·출발지·경로와 함께 보관하고 실제 Connect 동기화·사용자별 프로비저닝 결과는 별도 열에 남긴다.

공식 근거: Connect 연결·동기화 전제 · 사용량 동기화

진행 기준 / 완료 증거: 설치 전 설계 승인을 마치고 기동 후 DNS·TLS를 확인한다. IAM 연결 후 실제 Entra Test Connection·서버 로그 상관관계까지 네 가지 증거를 확보해야 SCIM 파일럿에 진입한다.

Phase 3VMware 어플라이언스 설치·초기 보호

상세 참조 장 · STEP 04의 실행 순서·화면으로 돌아가기 →

담당: 가상화·GHES 운영 수행자와 검증자선행: Phase 0–2 승인·공식 이미지·키·관리망산출물: 검증된 기반 인스턴스·관리 접근·IAM 인계서

3-1. 공식 이미지와 변경 창을 준비한다

  1. 진입 조건 확인

    Phase 0의 플랫폼·사양, Phase 1의 라이선스 파일, Phase 2의 FQDN·DNS·TLS·관리망을 준비한다. 수행자·검증자·중단 조건·지원 연락 경로를 정하고 초기 설정 동안 담당자가 자리를 비우지 않는다.

  2. 공식 OVA 확보

    3.21 Release notes에서 설치일에 승인한 지원 패치를 선택 → Download GitHub Enterprise Server X.X.X → GitHub On-premises의 VMware ESXi/vSphere (OVA) → Download. 비공식 재패키징 이미지를 사용하지 않는다.

  3. 출처·무결성 확인

    공식 다운로드 주소, 실제 파일명·버전·크기, vSphere가 표시하는 서명·발행자·인증서 검증 결과를 기록한다. 공식 checksum 또는 서명 검증 자료가 제공되면 그 값·방법과 대조한다. 임의 SHA 값을 만들어 기대값으로 쓰지 않는다. 서명·무결성 오류가 나면 우회하지 않고 재다운로드 또는 Support 확인 후 진행한다.

공식 근거: VMware 공식 이미지·배포 절차 · 설치할 패치 선택

3-2. vSphere에서 전원 투입 전 구성을 끝낸다

  1. 루트 용량 사전 결정

    원본 OVA를 보존하고 비클러스터 400 GB 루트 권장을 적용한다. 공식 VMware 가이드의 배포 전 OVF disk attributes 조정 경로를 따른다. 원본 무결성 검사와 승인된 템플릿 변경 기록을 구분하고, 변경 후 manifest·서명 오류가 있으면 검증 우회 없이 배포 담당과 해결한다. 부팅 후 임의 파티션 편집으로 맞추지 않는다.

  2. Deploy OVF Template

    vSphere Client에서 승인 호스트·클러스터를 선택하고 Deploy OVF Template로 공식 이미지를 가져온다. VM 이름·대상·데이터스토어·네트워크 매핑을 대조한다. 디스크와 향후 확장 여유가 충분한 datastore, 권장 Thick Provision Lazy Zeroed를 선택한다.

  3. 자동 전원 투입 해제

    Power on after deployment를 선택하지 않는다. 배포 후 Edit Settings에서 승인된 CPU·메모리·루트 용량·관리 경로를 다시 확인한다. 잘못된 네트워크 매핑은 최초 설정 화면을 외부에 노출할 수 있다.

  4. 새 데이터 디스크 연결

    Add New Device → Hard Disk에서 별도 새 데이터 디스크를 만들고 Phase 0의 승인 용량을 지정한다. 루트 디스크를 데이터 디스크로 착각하지 않도록 장치·용량을 대조한다. 데이터가 있거나 비어 있는지 증명할 수 없는 디스크는 연결하지 않는다.

  5. 부팅·네트워크

    검증자 확인 후 전원을 켠다. OS를 따로 설치하지 않는다. vSphere 콘솔에서 IP·gateway·DNS를 확인하고 필요 시 콘솔의 S 네트워크 설정에서 승인된 값을 입력한 뒤 D로 완료한다. 화면의 실제 옵션을 확인하며 원격 세션이 끊길 수 있는 변경을 무작정 반복하지 않는다.

공식 근거: VMware root·disk·power-on 지침 · 콘솔 DNS 설정

3-3. 최초 Console 설정과 웹 관리자 생성을 즉시 수행한다

초기 설정 화면 보호

최초 부팅 전부터 경계 방화벽으로 설치 담당자만 접근하게 한다. 초기 TLS는 자체 서명 상태일 수 있으므로 승인된 콘솔·호스트 확인 절차로 접속 대상을 확인한다. 자체 서명 경고를 영구 예외로 배포하지 않는다. 라이선스 업로드, root Console 암호 설정, 첫 웹 사용자 생성을 지연하면 다른 사람이 인스턴스를 선점할 수 있다.

  1. 라이선스·Console 암호

    관리자 브라우저에서 https://github.example.com/setup으로 최초 설정에 진입한다. Management Console은 HTTPS 8443 경로를 사용하므로 해당 관리 포트를 허용한다. 공식 파일을 업로드하고 최초 root Management Console 암호를 설정·금고에 보관한다.

  2. Hostname·DNS·Time

    Console의 Hostname에 승인된 FQDN을 지정한다. DNS resolver는 VM 콘솔에서 확인한 값을 사용하고 자신과 필수 외부 이름의 해석을 확인한다. Time의 Primary NTP server와 필요 시 Secondary NTP server를 지정한다. 호스트 이름을 시험용 별칭으로 시작한 뒤 운영명으로 바꾸는 방식을 피한다.

  3. 격리·TLS

    Hostname → Subdomain isolation (recommended)을 선택한다. TLS 설정에서 TLS only (recommended), 인증서/전체 체인, Unencrypted key를 지정한다. 버전별 TLS/Privacy 화면 배치를 확인하되 TLS 적용을 이유로 조직의 Private mode 정책을 임의로 해제하지 않는다. 기업 공개 범위 변경은 별도 승인 사항이다.

  4. 검토 후 Save settings

    hostname·DNS·NTP·라이선스·TLS·인증 방식을 검증자와 대조한다. Actions는 외부 저장소·인증·runner 설계가 완료될 때까지 비활성 상태로 둔다. Save settings 후 구성 실행이 완료되고 최초 재시작이 끝날 때까지 기다린다. 일반 설정 저장도 서비스 재시작·사용자 중단을 유발하므로 변경 창을 적용한다.

  5. 첫 웹 사용자

    Visit your instance로 이동해 첫 built-in 웹 관리자 계정을 즉시 만든다. 강한 암호와 복구 수단을 보관하고 제공되는 2FA를 설정한다. 첫 관리자 권한과 Enterprise settings 접근을 확인한 후 일반 사용자에게 서비스를 공개한다. 최초 Console 암호를 이 웹 계정 암호로 재사용하지 않는다.

  6. 후속 IAM 인계

    SAML과 SCIM 단계는 별도 변경이다. SCIM에는 공식 절차의 built-in scim-admin enterprise owner가 필요하다. 첫 웹 관리자와 자동으로 같다고 가정하지 않는다. SAML 전환 전에 비상 로그인·승격·중복되지 않는 사용자명과 이메일을 검증한다. 여기서는 SCIM 토큰을 발급하지 않는다.

공식 근거: Console 진입 · TLS 필수 형식·중단 · 하위 도메인 설정 · 시각 설정 · SCIM built-in setup user

3-4. 관리 접근을 역할별로 분리하고 SSH를 검증한다

접근 영역인증운영 원칙
웹 site administrator / enterprise owner웹 계정의 built-in 또는 후속 SAML 인증웹 정책·사용자 관리 역할. Console 사용자 및 SSH 사용자와 별도.
Management ConsoleRoot site admin 암호 또는 별도 Console 사용자명·자격증명Root로 User Management → Create user에서 운영자 생성 가능. 운영자는 다른 Console 계정을 생성·삭제하지 못한다.
관리 SSH TCP 122고정 사용자 admin + Console에 승인된 개인별 공개키웹 Settings의 Git SSH 키와 별도. 개인키는 PC/승인 키 저장소에 남기며 서버나 문서에 복사하지 않는다.
  1. 공개키 등록

    웹 Site admin → Management Console → SSH access → Add new SSH key에 운영자 공개키만 붙여넣고 Add key를 누른다. 소유자·지문·회수일을 기록한다. 이 변경은 즉시 적용되며 이를 위해 Save settings를 누를 필요가 없다.

  2. 호스트 지문 대조

    최초 SSH 연결 전 서버 호스트 키 지문을 승인된 콘솔 또는 별도 신뢰 경로로 확보한다. 프롬프트의 지문과 대조한 뒤 승인한다. 호스트 키 확인을 끄거나 변경된 키를 무조건 삭제해 접속하지 않는다.

로컬 세션·파일 · 승인된 관리망 PC; ./approved-admin-key는 기존 승인 개인키 경로 · bash
ssh -p 122 -i ./approved-admin-key admin@github.example.com
판정: 검증한 호스트 키의 admin 관리 셸에 접속한다. 최초 승인 시 로컬 known_hosts가 갱신될 수 있다. Permission denied (publickey)이면 122·admin·키 경로·Console 등록을 확인한다.
조회 · 접속한 GHES의 승인된 관리 셸 · bash
ghe-version
ghe-system-info
ghe-config core.github-hostname
ghe-license check
df -h
free -h
판정: 승인한 실제 버전·hostname·키 유효성을 대조한다. ghe-system-info는 JSON 시스템 정보다. df/free는 일반 읽기 전용 현황 조회이며 공식 사이징 검사나 부하 시험을 대체하지 않는다. root의 약 절반 예약과 별도 데이터 마운트를 확인한다.

출력에 포함된 시스템 식별자·네트워크 정보는 제한된 운영 기록에만 보관한다. root 여유가 예상보다 작다고 패키지 삭제·파티션 포맷·OS 업데이트를 실행하지 않는다. 설정값 전체 덤프 대신 필요한 hostname만 조회하고, 저장소·토큰·개인키가 포함될 수 있는 로그를 공개 공유하지 않는다.

완료 항목남길 증거실패 시 조치
버전·디스크승인 패치와 실제 버전 일치, 루트/데이터 장치 및 용량다르면 사용자 유입 전 중단. 데이터 디스크를 덮어쓰거나 강제 초기화하지 않는다.
DNS·TLS·NTPFQDN과 하위 도메인 검사, 체인·SAN·만료, Time 상태·동기화 확인Phase 2로 돌아가 원인을 수정. 연결 실패를 TLS 해제나 무조건 재저장으로 우회하지 않는다.
라이선스키 check, 한도·만료일, 별도로 확인한 사용량파일·계약·적용 시점 확인 후 구매 또는 Support에 문의.
관리·비상 접근첫 웹 owner 접근, Console 운영자, 122 공개키 지문·소유자, 비상 자격증명 금고역할별 로그인 성공을 개별 확인. 웹 로그인만으로 전체 관리 접근 성공 처리하지 않는다.
구성 실행Save settings 완료 시각·오류 유무·서비스 복귀오류 화면·시각·변경값을 보존하고 원인을 분리. 설정 적용 중 강제 재부팅·재배포 금지.
다음 단계로 넘어가는 범위

이 단계는 기반 설치 완료이지 운영 전체 승인이나 SCIM 검증 완료가 아니다. 다음은 SAML·SCIM의 제한된 파일럿이다. Actions는 외부 Blob·인증·네트워크·runner·용량이 준비된 별도 단계에서만 켠다. 운영 서비스 개시 전에는 RPO/RTO에 맞는 백업·복원 시험도 완료해야 한다.

공식 근거: 개인별 Console 계정 · SSH 키·즉시 적용·지원 제한 · 읽기 도구·시스템 정보 · 저장소·복구 구조

진행 기준 / 완료 증거: hostname·TLS·버전·라이선스·분리 디스크·첫 owner·Console·SSH 키를 검증하고 초기 설정 오류가 없어야 한다. SAML/SCIM 및 Actions의 미완료 항목을 명시해 인계한다.

Phase 4관리 복구 경로와 Entra SAML 인증

상세 참조 장 · STEP 05의 실행 순서·화면으로 돌아가기 →

담당: GHES·Entra 관리자선행: TLS·백업·이관 승인산출물: 계정 구분표·SAML 매핑·복구 증거

적용 기준과 작업 경계

GitHub와 Microsoft의 공식 문서를 기준으로 인증·프로비저닝·권한·라이선스 운영 절차를 설명하는 GHES 3.21 가이드다. 3.22 및 다른 패치의 UI·동작은 해당 버전에서 재검증한다. Cloud Enterprise Managed Users(EMU)의 초기 계정·OIDC·API 경로를 그대로 복사하지 않는다. 이 문서의 도메인과 계정은 예시이며, 명령은 승인된 환경에서 담당자가 실행하는 절차이지 실행 결과가 아니다.

SAML은 로그인, SCIM은 계정 수명주기, 조직 팀은 저장소 권한을 담당한다. 먼저 관리 복구 경로를 확보하고, 소수 파일럿으로 인증·프로비저닝·인가를 각각 검증한다.

사용자 수명주기: SAML 인증과 SCIM 관리를 분리 동일한 로컬 Excalidraw 도형 데이터로 생성한 설명용 SVG. 편집기 내보내기가 아니며 HTML의 Clawpilot 테마를 상속합니다. 사용자 수명주기: SAML 인증과 SCIM 관리를 분리 GHES용 Entra 앱을 사용 · GHEC 사용자 정보 동기화나 즉시 반영을 의미하지 않음 초기 구성 · GHES 내장 설정 계정 초기 운영자 승인된 관리 콘솔 접근 내장 설정 계정 scim-admin 운영자가 직접 생성 비상 접근·SCIM 구성용 SCIM용 PAT classic scim:enterprise 비밀 보관소·IdP에 저장 인증 경로 · 사용자 브라우저가 중개 Entra ID / SAML objectidentifier 확인 NameID는 별도 검토 GHES 사용자 로그인 SCIM externalId와 식별자 연결 검증 파일럿 통과 조건 Enterprise owner 실제 로그인 성공 SAML 프로비저닝 경로 · Entra 서비스가 GHES API 호출 Entra GHES 앱 Users / Groups 할당 프로비저닝 범위 SCIM 생성·갱신 externalId 매핑 비활성화 처리 GHES 사용자 수명주기 관리 로그·반영 상태 확인 Org · Team 리포지토리 권한 별도 정책 검증 검증 후 확대 파일럿으로 로그인·생성·권한·비활성화 확인 → 로그 점검 후 대상 확대 할당 범위와 권한 정책은 별도 확인 · 동기화 주기·오류에 따라 반영 지연 가능 SAML 식별자와 SCIM externalId의 안정적인 연결이 핵심 · 클라우드 계정 자동 복제 경로 없음 설명용 개념도 · 실제 화면이나 고객 환경이 아님 · 연결은 주요 논리 흐름만 표시
설명용 개념도. 인증·프로비저닝·리소스 권한은 별개입니다. setup 계정과 SCIM 운영 Owner를 구분하고 한 명의 전체 접근을 먼저 검증합니다.

4.1 관리 계정은 네 종류로 구분한다

종류인증·범위운영 원칙
GitHub 웹 계정 / site administrator / enterprise ownerGHES 웹의 Enterprise settings, 사용자·조직 관리웹 관리 권한과 Management Console 접근 자격을 혼동하지 않는다. 일반 사용자에게 Owner를 주지 않는다.
Management Console root site administrator / Console 사용자인스턴스 설정용 별도 계정·암호, 일반적으로 HTTPS 8443root 복구 암호와 개인별 Console 접근을 보호한다. 웹 계정 암호나 GitHub.com 계정과 같지 않다.
관리 SSH의 admin등록된 관리 공개키, TCP 122Git SSH의 git 사용자·키와 별도이다. 관리키를 개발자 공용키로 사용하지 않는다.
built-in SCIM setup 계정 scim-admin운영자가 GHES에서 생성하는 로컬 웹 계정, enterprise ownerCloud의 shortcode_admin이나 GitHub 환영 메일로 받는 setup 계정이 아니다. 별도 금고·담당자·복구 시험이 필요하다.

4.2 변경 전 입력표

입력예시 / 수집 위치승인·검사
서비스 URL / 버전https://github.example.com / 설치된 3.21.xTLS 체인·DNS·시각 동기화, 버전별 문서와 일치
Entra 관리 범위example-ghes 앱의 Application Owner 또는 필요한 Application Administrator 역할앱 생성·설정 권한과 그룹·Conditional Access 관리 권한을 분리하고 상시 Global Administrator 사용을 피한다.
복구 담당 / 로컬 계정scim-admin / identity+admin@example.comSCIM 대상과 username·email이 겹치지 않도록 한다.
파일럿pilot.reader@example.com, pilot.owner@example.com일반 계정과 Owner 승격용 계정을 분리한다.
기존 계정 대응표기존 login ↔ 정규화된 UPN ↔ Entra 사용자 Object ID충돌·이메일 덮어쓰기·계정 연결 대상을 변경 전에 검토
변경 창 / 복구백업 완료 시각, 복원 검증, Console·SSH 담당기존 LDAP/CAS 전환과 SCIM 활성화는 별도 이관 창을 잡는다.
기존 인스턴스에서는 인증 스위치만 바꾸지 않는다

SCIM 활성화 후 기존 SAML 사용자는 SCIM으로 프로비저닝되기 전까지 로그인할 수 없다. 기존 계정은 정규화된 userName과 기존 username 비교로 연결될 수 있고 이름·이메일 및 추가 이메일이 변경될 수 있다. LDAP/CAS와 SCIM을 혼용하지 않는다. 스테이징에서 계정 매칭과 복구를 검증하고 백업·중단 공지를 승인한다.

4.3 복구 계정 → Entra 앱 → GHES SAML

  1. built-in 복구 경로 준비

    Site admin → Management Console → Authentication에서 기존 SAML 사용 시 Allow creation of accounts with built-in authentication과 Disable administrator demotion/promotion을 선택한다. 후자는 설정 중 IdP 밖에서 관리자 권한을 부여하기 위한 임시 상태다. 승인된 변경 창에서 Save settings → 구성 적용 성공을 확인한 뒤 다음 계정 생성·승격으로 진행한다. 선택만 하고 저장하지 않은 상태로 넘어가지 않는다.

  2. scim-admin 생성과 독립 로그인

    Site admin → Invite user에서 예시 username·별도 이메일을 입력하고 Generate a password reset link를 사용한다. 새 비공개 창에서 초기 암호를 설정·금고 보관한다. 기존 관리자가 Enterprise settings → People → Administrators → Add owner에서 scim-admin을 검색해 Add로 enterprise owner를 부여한다. https://github.example.com/login의 built-in 로그인 경로로 재접속한다. 이 계정을 SAML에 연결하면 username/password 로그인 선택권을 잃을 수 있으므로 IdP 파일럿으로 사용하지 않는다. 독립 Console 복구 접근과 built-in 계정의 2FA·복구 코드도 확인한다.

  3. 동일 파트너 앱 생성

    Entra ID → Enterprise apps → New application → 갤러리의 GitHub Enterprise Server를 추가한다. (Legacy) 앱은 제외한다. 같은 앱으로 SAML과 SCIM을 구성한다. 기존 Legacy/SAML 앱에서 옮길 때 GHES 3.21 가이드는 새 앱 구성을 요구하므로 할당·claims·SCIM 매핑을 검토해 이관한다. 최신 Entra 문서의 기존 앱 재사용 문구만 근거로 기존 앱을 즉시 전환하지 않는다.

  4. 인증 전환 전에 로그인 대상 할당

    새 앱의 Users and groups → Add user/group에서 승인된 일반 SSO 파일럿을 먼저 할당한다. 기존 사용자 이관이면 변경 창에서 인증이 필요한 승인 대상도 전환 전에 할당·역할·접근 정책을 대조한다. 앱 할당이 필요한 구성에서 미할당 상태로 GHES 인증부터 바꾸지 않는다. 이때 SCIM 자동 프로비저닝은 아직 시작하지 않으며, 사용자 생성·Owner 검증은 Phase 5에서 별도 수행한다.

  5. Entra SAML 기본값 입력

    앱 → Single sign-on → SAML → Basic SAML Configuration → Edit에서 아래 표를 입력한다. SAML certificates의 Certificate (Base64)를 받고 Set up GitHub Enterprise Server의 Login URL, Microsoft Entra Identifier를 수집한다.

  6. GHES에서 IdP 값 연결

    Site admin → Management Console → Authentication → SAML에서 Single sign-on URL에 Login URL, Issuer에 Microsoft Entra Identifier, Verification certificate에 Base64 인증서를 넣는다. Signature Method·Digest Method는 IdP 서명 구성에 맞추고 Name Identifier Format도 실제 claim과 일치시킨다. User attributes를 검토하고 두 setup 옵션을 유지한다. IdP initiated SSO는 특별한 필요와 검증 없이 켜지 않는다.

  7. 변경 저장과 파일럿 인증

    Management Console의 Save settings와 적용 진행 상태를 확인한다. 설정 적용은 서비스 재시작·중단 영향을 줄 수 있으므로 완료까지 변경 창과 복구 세션을 유지한다. 별도 브라우저에서 GHES 로그인 → Entra 인증 → GHES 복귀를 시험한다. Cloud의 Test SAML configuration 버튼이 GHES에도 있다고 가정하지 않는다. Entra의 Test this application은 별도 기능이다.

필드입력 / 매칭주의
Identifier (Entity ID)https://github.example.comGHES 호스트 기준, Cloud enterprise URL 아님
Reply URL (ACS)https://github.example.com/saml/consume대소문자·프로토콜·경로 확인
Sign on URL (SP initiated)https://github.example.com/ssoMicrosoft 공식 패턴. 해당 GHES의 로그인 흐름으로 검증
NameID / Username안정적으로 관리할 UPN 등 실제 앱 claim과 GHES 사용자 속성persistent URI 형식을 무조건 강제하지 않는다. UPN 변경·정규화 충돌 계획과 신원 키를 구분한다.
http://schemas.microsoft.com/identity/claims/objectidentifierEntra 사용자 Object ID = SCIM externalId값이 정확히 같아야 한다. 앱의 Application(client) ID나 service principal Object ID가 아니다.
MFA·인증서 교체·복구

MFA와 Conditional Access는 Entra SAML 로그인에서 검증한다. GHES는 Cloud OIDC/CAP 네이티브 통합이 아니며 모든 PAT 요청마다 CAP가 평가된다고 약속하지 않는다. PAT·SSH·네트워크 접근 정책은 별도로 관리한다. 인증서 교체는 새 IdP 인증서와 GHES verification certificate를 조율해 갱신한다. SAML 비활성화로 해결하지 않는다. GHES가 인증서 만료를 강제하지 않아도 IdP 키 변경 후 불일치하면 digest mismatch가 발생한다.

조회 · 승인된 관리자 PC · bash
curl --head --silent --show-error --connect-timeout 10 https://github.example.com/login
판정: 신뢰할 수 있는 TLS와 HTTP 응답·리디렉션을 확인한다. 이것만으로 SAML 성공이나 Entra의 SCIM 도달성을 증명하지 않는다.

파일럿 증거: 로그인 시각, 앱 이름, 익명화한 사용자 Object ID, Entra sign-in 결과, GHES login을 대응시킨다. SCIM을 아직 켜지 않았다면 JIT 결과이며 Phase 5 후 다시 시험한다. SAML assertion 원문·암호·토큰은 공유 보고서에 붙이지 않는다.

공식 근거: 3.21 SAML 설정 · 3.21 built-in 인증 · 3.21 Entra 통합 · Entra SAML UI·/sso · Console 계정 경계 · 3.21 setup 계정 Owner 승격 · 관리 SSH 122

진행 기준 / 완료 증거: 별도 built-in·Console 복구와 일반 파일럿 SSO 확인. SCIM 전환 창 승인.

Phase 5SCIM 프로비저닝과 사용자 수명주기

상세 참조 장 · STEP 06의 실행 순서·화면으로 돌아가기 →

담당: 신원·GHES 운영자선행: Phase 4·IdP의 API 도달성산출물: 할당·매핑·Owner·퇴사/복귀 증거

5.1 활성화 전 조건과 자격 증명

버전과 네트워크 경계

GHES SCIM은 3.14의 public beta를 거쳐 3.17에서 GA가 되었다. 아래 절차는 3.21 기준이다. Entra 프로비저닝 서비스가 GHES의 HTTPS 443 SCIM API에 도달해야 한다. 관리자 PC에서만 접속되는 VPN은 충분하지 않다. GitHub Connect의 outbound 연결이 SCIM inbound 경로를 대신하지 않는다.

항목입력 / 설정검증
토큰 소유자built-in enterprise owner scim-admin일상 사용자·퇴사 예정 계정 토큰 금지
PAT 종류·scopepersonal access token (classic), scim:enterprise만fine-grained PAT·GitHub App 토큰은 SCIM API에서 지원하지 않는다.
만료No expiration (3.21 setup 문서 요구)별도 비밀 금고·회전 담당·교체 시험. 일반 개발자 PAT 정책의 예외로 승인한다.
Tenant URLhttps://github.example.com/api/v3/scim/v2api.github.com 또는 enterprises/{slug} 경로를 사용하지 않는다.
Secret Tokensetup 계정의 PAT를 금고에서 입력표·명령줄·스크린샷·프로비저닝 로그에 값 표시 금지
할당 범위Sync only assigned users and groups일반 파일럿 1명과 Owner 후보 1명부터 시작
  1. 전용 classic PAT 발급

    scim-admin으로 로그인 → Settings → Developer settings → Personal access tokens → Tokens (classic)에서 생성한다. 위 scope와 No expiration을 선택하고 값은 즉시 금고에 저장한다. 토큰은 자동 OIDC 교환 방식이 아니다.

  2. GHES에서 SCIM 활성화

    scim-admin → Enterprise settings → Settings → Authentication security → SCIM Configuration → Enable SCIM configuration을 선택한다. 감사 로그의 business.enable_open_scim과 기존 사용자 영향 범위를 확인한다. SAML은 계속 활성 상태로 유지한다.

  3. Entra 연결 설정

    같은 GitHub Enterprise Server 앱 → Provisioning → Get started → Automatic → Admin Credentials에서 Tenant URL·Secret Token 입력 → Test Connection → 성공 후 Save. 연결 시험 성공은 사용자 생성·역할·팀 권한의 성공을 의미하지 않는다.

  4. 매핑과 범위 고정

    Mappings의 사용자·그룹 매핑을 검토한다. 기본 objectId → externalId, userPrincipalName → userName, email·active·이름 값을 확인한다. roles의 실제 갤러리 expression·출력 값을 보존하고 임의 상수로 바꾸지 않는다. Scope는 할당된 사용자·그룹만으로 설정·저장하고 알림 담당 및 대량 삭제 방지 설정을 검토한다.

  5. 일반 사용자와 Owner 직접 할당

    Users and groups → Add user/group에서 일반 파일럿은 일반 역할, Owner 후보는 실제 제공되는 Enterprise Owner 역할로 직접 할당한다. 역할명이 다르면 앱·버전과 roles payload를 확인한다. Owner 그룹 상속만으로 승격을 추정하지 않는다. 그룹은 Security group만 사용하며 중첩 그룹과 Microsoft 365 그룹은 지원하지 않는다.

  6. 일반 파일럿의 계정 생성·매칭 확인

    Provision on demand로 정확한 일반 파일럿 한 명을 선택해 실행한다. 이는 계정 상태를 쓰는 변경 작업이며 조회가 아니다. 대상 ID·externalId·active와 Steps의 실제 action·결과를 확인한 뒤 SAML 로그인도 별도로 시험한다. 이 성공을 Owner 역할 반영이나 조직·저장소 권한의 성공으로 해석하지 않는다.

  7. Owner 제어 전환·적용

    복구 세션을 유지한 승인 창에서 Management Console의 Disable administrator demotion/promotion을 해제한다. 선택 상태이면 SCIM으로 enterprise owner를 부여할 수 없다. Save settings → 구성 적용 성공과 비상 접근 유지를 확인한 뒤 다음 정기 동기화 단계로 진행한다. 기존 SAML administrator claim에 의한 승격·강등 영향도 조사한다. 적용 실패나 복구 접근 상실 시 진행하지 않는다.

  8. 승인된 파일럿 범위의 정기 동기화·Owner 검증

    Overview → Start provisioning으로 승인된 파일럿 범위 전체의 처리를 시작한다. 이미 Running이면 재시작하지 않고 다음 정기 동기화의 대상별 결과를 확인한다. Off·Stopped이면 중지 사유와 누적 변경을, Quarantine이면 원인을 먼저 해결한다. 실제 roles 출력·GHES Owner 목록·새 브라우저 SSO를 모두 확인한다. GHES의 SCIM Owner 프로비저닝 지원과 Microsoft의 on-demand 역할 프로비저닝 미지원은 다른 범위의 설명이다. Owner 후보의 on-demand는 계정 생성·매칭 확인에 한정하며 성공만으로 Owner 반영을 판정하지 않는다. 초기 전체 평가와 이후 증분 주기를 구분한다. 약 40분은 앱별 주기 확인이 필요한 일반 안내이며 전체 앱의 SLA나 개별 사용자 완료 보장이 아니다.

  9. 검증 완료 후 대상 확대

    일반 사용자와 운영 Owner의 계정·SSO·역할을 각각 검증하고 setup 계정의 권한·built-in 로그인·PAT가 유지되는지 확인한 후 일상 관리를 위임하고 승인된 대상을 확대한다. built-in 생성 허용 해제는 선택 사항이며 복구 경로 영향을 검증하기 전에는 끄지 않는다. reset·재생성으로 우회하지 않는다.

문서 간 차이는 버전 기준으로 처리

최신 Microsoft provisioning 안내에는 새 UI와 /api/v3/scim 경로가 보일 수 있다. 본 절차는 GHES 3.21 전용 Entra 가이드의 /api/v3/scim/v2, Test Connection → Save를 기준으로 한다. 실제 갤러리 앱이 다르면 버전·화면·응답을 확인한 뒤 진행하며 Cloud 경로로 대체하지 않는다.

5.2 Entra Provisioning logs부터 확인한다

  1. 정확한 앱과 할당 이후 시간으로 조회

    Entra ID → Enterprise apps → 해당 GitHub Enterprise Server 앱 → Provisioning logs를 연다. Provisioning 화면에서 로그로 이동하는 UI라면 같은 앱·configuration인지 확인한다. Sign-in logs는 SAML 인증 기록이지 SCIM 생성 기록이 아니다. 앱의 service principal Object ID와 사용자 source Object ID를 먼저 대조하고, 시간 범위는 앱 할당 시각 이후로 잡는다. 화면의 시간대를 기록하여 UTC로 환산한다. 표시 이름·UPN만 같은 다른 앱이나 다른 사용자 로그를 섞지 않는다. F4 로그 목록을 참고한다.

  2. 행의 Action·Status와 Steps를 함께 읽기

    사용자 행을 열어 Steps의 Import user → Determine scope → Match → Perform action을 확인한다. 실패 시 Test connection 단계도 확인한다. 매칭된 대상과 Modified properties의 externalId·userName·active·실제 roles를 대조한다. 실패 화면의 속성은 전송 시도 값일 수 있으므로 실제 반영으로 취급하지 않는다. F5 Steps와 F7 결과를 참고한다.

  3. GHES와 같은 UTC 구간으로 상관 분석

    앱 Object ID, source Object ID, Action·Status, UTC 시각, Target ID, Change ID, 표시되는 job ID·request ID와 오류 본문을 승인된 기록에 남긴다. Change ID는 Entra 이벤트·Steps·변경 속성 연결 키이며 GHES request ID와 같은 값이라고 가정하지 않는다. GHES 감사 로그·SCIM 조회의 externalId와 SCIM User ID를 같은 UTC 구간에 대조한다. Token·개인정보를 제거한 뒤 공유한다.

Action / 관찰판정다음 확인
Create + Success대상 생성 성공 기록정확한 Target ID·externalId·GHES 계정을 확인한다. 또 40분을 기다려야 생성되는 상태가 아니다.
Update + Success기존 대상의 속성·상태 업데이트새 계정 생성 증거가 아니다. 매칭 대상과 active·변경 속성을 확인한다.
Disable / Delete접근 제거·수명주기 변경생성 실패와 구분한다. 실제 요청·응답과 soft/hard 영향을 확인하며 재할당을 서두르지 않는다.
Skipped평가되었으나 작업 생략Steps의 scope·필터·역할·변경 없음 이유를 읽는다. 생성 성공과 같지 않다.
조회 결과 0건선택한 필터·시간 범위에서 기록 미확인실패·성공 어느 쪽도 증명하지 않는다. 앱·Object ID·시간·할당 전파·job 상태부터 확인한다.
생성·로그인·권한의 완료 증거는 별개

SCIM Success는 조직 가입이나 저장소 권한의 성공이 아니다. Create가 확인되면 SAML 로그인·조직 팀·Private 접근으로 검증을 이어간다. GHES UI 표시까지의 고정 완료 시각을 약속하지 않는다.

조회 전용 진단: 기존 승인 토큰만 사용

다음은 Bash subshell에서만 토큰을 유지하는 GET 예시다. gh가 설치된 신뢰할 수 있는 관리자 PC에서 실행한다. 토큰 자체는 쓰기 권한도 가지므로 조회 명령이라고 읽기 전용 자격 증명으로 착각하지 않는다. 세션 녹화·환경 수집도 금지한다.

조회 · 승인된 관리자 PC · bash
(
  set +x
  unset GH_DEBUG GH_TOKEN GITHUB_TOKEN GITHUB_ENTERPRISE_TOKEN GH_ENTERPRISE_TOKEN
  IFS= read -r -s -p 'Approved SCIM classic PAT: ' GH_ENTERPRISE_TOKEN
  printf '\n'
  test -n "$GH_ENTERPRISE_TOKEN" || exit 1
  export GH_ENTERPRISE_TOKEN
  export GH_PROMPT_DISABLED=1 GH_PAGER=cat
  gh api --hostname github.example.com --method GET \
    'scim/v2/Users?startIndex=1&count=10' \
    --jq '{totalResults, startIndex, itemsPerPage, Resources: [.Resources[] | {id, externalId, userName, active}]}'
)
판정: HTTP 성공과 SCIM ListResponse를 확인한다. 출력은 개인정보이므로 승인된 담당자만 열람한다. 비밀은 인수·URL·파일에 넣지 않는다.

Users는 대소문자를 구분한다. gh가 GHES의 /api/v3 접두어를 처리한다. 필요한 페이지에 한해 startIndex를 실제 반환 건수만큼 증가시키고 count·totalResults·itemsPerPage를 확인한다. 빈 페이지면 중단하며 gh --paginate로 일반 REST 페이지 규칙을 무조건 적용하지 않는다. scim/v2/Groups?startIndex=1&count=10도 같은 GET 방식으로 조회한다.

5.3 오류는 대상 사용자와 응답 본문으로 분류한다

관찰읽기 전용 확인다음 조치
로그에 대상 없음 / Skipped정확한 UPN·Object ID·시각, 앱 할당, Scope·필터·소스 상태성공한 다른 사용자 로그로 판정하지 않는다. 범위를 승인 후 수정한다.
400SCIM detail, 필수 속성·정규화 충돌·User-Agent실제 오류 속성과 갤러리 매핑을 비교한다.
401 / 403토큰 유효성·소유자 상태·scim:enterprise, 네트워크 중간 장비 응답인증 실패와 권한 거부를 분리한다. 광범위 scope 추가 금지
404 / 409정확한 endpoint·대소문자·SCIM 활성화 / 기존 username·externalId잘못된 URL과 충돌을 본문으로 구분하고 계정을 삭제하지 않는다.
라이선스 관련 오류 문구오류 원문·request ID·GHES 패치·설치 라이선스·사용량3.21 문서는 새 SCIM 계정 프로비저닝에 가용 라이선스가 필요 없다고 명시한다. 실제 out-of-seats라면 별도 증거로 Support에 확인한다.
429 / 재시도 / 격리Entra Provisioning logs의 실패 단계·재시도·quarantine 및 GHES 감사 로그초기 대량 작업과 증분을 분리하고 제공자 재시도 정책을 따른다. 재시작·전체 재프로비저닝을 반복하지 않는다.
생성 성공, 로그인 실패objectidentifier = externalId, NameID/username 정규화, active 상태SAML·SCIM 매칭을 수정한다. MFA 성공만으로 GHES 로그인 성공이라고 판정하지 않는다.
쓰기는 IdP 한 곳에서만

파트너 앱 사용 시 SCIM POST·PUT·PATCH·DELETE는 IdP만 수행한다. 임의 POST로 사용자·그룹을 고치면 후속 동기화가 깨질 수 있다. 토큰·개인정보를 제거한 오류 본문과 타임라인을 Support에 전달한다. 라이선스 오류를 알려진 버그라고 단정하거나 특정 패치의 해결을 약속하지 않는다.

5.4 퇴사·복귀와 좌석 검증

경로GHES 3.21 영향검증
Soft deprovisionEntra 비활성화·앱 할당 해제 등으로 정지, username 해시화, 연결 신원 유지세션·private 접근 차단, 그룹 팀 제거를 확인한다. 수동 조직 멤버십은 정지 상태로 남을 수 있다.
같은 IdP 객체 복귀같은 externalId·SCIM User ID로 재활성화 가능동일 UPN의 새 Entra 객체는 복구가 아니다. 재할당 후 SSO·권한·자격 증명을 재확인한다.
Soft 복귀 시 자료PAT·SSH 키·앱 승인 등이 복원될 수 있고 private/internal fork는 24시간 내 삭제, 90일 내 복귀 시 복원보안 사고 계정은 이전 자격 증명까지 안전하다고 가정하지 않는다. 조직 복구의 90일 조건도 확인한다.
Hard deprovisionEntra 영구 삭제 등은 복원 불가. 신원 연결·토큰·키·앱 승인·개인 저장소 삭제, 댓글 등은 유지Entra soft-deleted 객체의 30일 후 영구 삭제를 주의한다. 동일 이름 새 계정으로 원래 계정을 합칠 수 없다.
GHES 좌석성공적으로 인증한 active 사용자와 dormant 사용자가 기준. 조직 가입은 필수 조건이 아니다.정지 완료와 사용량 반영을 확인한다. 팀·조직에서만 제거했다고 좌석이 해제되지는 않는다.
setup 계정 예외scim-admin은 생성 시 소비하다 SCIM 활성화 후 면제; 다른 이름은 계속 소비초과 사용을 숨기려고 계정을 삭제·재생성하지 않는다. 라이선스 파일·실사용·계약을 대조한다.

5.5 초기 동기화가 끝난 뒤 신규 사용자 1명 추가

Entra 디렉터리에 사용자를 만들었다는 사실만으로 GHES 앱에 할당되지는 않는다. 먼저 5.2 로그를 확인하고 다음 순서로 누락 지점을 좁힌다. 기존 계정 삭제·임의 역할 승격·전체 Restart provisioning으로 진단하지 않는다.

  1. GHES 앱과 사용자 신원을 정확히 고정

    Enterprise apps의 예시 example-ghes 앱 Overview/Properties에서 service principal Object ID를 정확히 기록한다. Application (client) ID나 App registrations 객체 ID가 아니다. Admin Credentials의 Tenant URL은 https://github.example.com/api/v3/scim/v2, 일반형은 https://HOST/api/v3/scim/v2다. GHEC EMU의 https://api.github.com/scim/v2/enterprises/SLUG와 구분한다. 사용자 Overview의 Object ID를 source identity와 정확히 비교한다. 이것이 기본 매핑의 SCIM externalId이며 앱 Object ID와 다르다. 같은 UPN의 재생성 객체는 같은 사용자가 아니다.

  2. 유효한 직접 할당 또는 그룹의 직접 멤버인지 확인

    앱 → Users and groups에서 사용자 직접 할당 또는 앱에 직접 할당된 Security group의 직접 멤버인지 확인한다. SecurityEnabled=true인 그룹을 사용한다. 중첩 그룹 멤버는 지원되지 않으며, 동적 그룹은 membership rule 평가·처리 완료를 먼저 확인한다. 그룹 평가 지연은 SCIM job 지연과 별개다. 빈 그룹이 있어도 별도로 유효한 사용자 직접 할당을 취소하지 않는다. F1 앱 할당을 참고한다.

  3. app role·매핑·Scope를 분리해 점검

    앱 Owners는 Entra 앱 관리 권한이고 Users and groups의 app role 할당이 아니다. 직접 할당과 그룹 할당의 중복·서로 다른 역할, Default Access, roles 매핑 expression·실제 출력을 검토한다. Default Access 처리 여부는 앱의 역할·scoping 조건으로 확인하며 무조건 성공 또는 실패라고 단정하지 않는다. 일반 사용자의 누락을 Enterprise Owner 부여로 우회하지 않는다. Provisioning → Overview → Properties(기존 UI의 Settings)에서 Sync only assigned users and groups와 사용자 scoping filter·소스 활성 상태를 확인한다. F3 Scope·Properties를 참고한다.

  4. 정상 실행 중이면 다음 증분 대상인지 확인

    Provisioning mode가 Automatic, status가 On, job이 Running이고 할당·Scope 조건을 충족하면 신규 사용자는 다음 증분 평가 대상이다. 최초 전체 sync를 다시 시작할 필요가 없다. 앱의 실제 주기·last cycle·진행 상황과 해당 사용자 로그로 확인한다. 긴급한 승인 대상 1명은 5.7 on-demand 분기를 사용한다.

5.6 Automatic 설정과 실행 상태를 구분한다

관찰의미안전한 다음 단계
Automatic / On / Running자동 모드로 job 실행 중할당·Scope를 통과한 신규 사용자는 다음 증분 평가. 초기 sync 완료 여부와 대상별 로그 확인
Off프로비저닝 상태가 꺼짐설정만 저장해도 실행된다고 보지 않는다. 중지 사유·전체 구성 범위를 검토하고 승인 후 활성화
Stoppedjob이 중지됨중지 주체·사유·누적 변경을 확인한다. 승인 후 Start provisioning으로 구성 범위 전체 처리를 재개
Quarantine지속 오류 때문에 처리·재시도 빈도가 감소한 격리 상태자격 증명·네트워크·대상 오류를 먼저 해결하고 해제·다음 cycle 확인. Off나 정상 대기와 혼동 금지

F2 Provisioning Overview에서 상태와 마지막 실행을 읽는다. Start provisioning은 선택한 1명만 보내는 버튼이 아니다. 시작·재개 시 현재 구성된 전체 Scope의 생성·변경·비활성화 영향을 승인받는다. Restart provisioning은 watermark를 초기화하여 전체 소스 재평가를 유발하므로 신규 1명 추가나 로그 0건의 기본 해결책으로 사용하지 않는다.

5.7 Provision on demand: 승인된 1명의 실제 쓰기

  1. 실행 전 변경 대상과 상태 승인

    정확한 GHES 앱·Tenant URL·source Object ID·할당·필터를 재확인한다. on-demand는 미리보기나 조회가 아니며 Create·Update·Disable을 수행할 수 있다. 앱에서 할당 해제된 사용자를 선택하면 비활성화할 수도 있다. Entra에서 비활성화·삭제되어 검색되지 않는 사용자를 같은 방식으로 처리할 수 있다고 가정하지 않는다. 새 할당은 on-demand에 전파되기까지 몇 분 걸릴 수 있다.

  2. 선택한 사용자 한 명 실행

    앱 → Provisioning → Provision on demand에서 예시 pilot.reader@example.com을 검색하고 source Object ID로 확인한 한 명을 선택한 뒤 승인된 경우에만 Provision을 누른다. GHES의 long-lived bearer PAT 방식은 on-demand를 위해 자동 job을 Stop할 필요가 없다. OAuth 방식인 다른 앱의 정지 요구를 GHES에 적용하지 않는다. F6 사용자 선택를 참고한다.

  3. 결과를 판정하고 다음 검증으로 이동

    View details / Steps에서 scope·match·action과 Target ID를 확인한다. Microsoft의 통상 30초 미만은 on-demand job 처리 안내이지 보장 시간이나 GHES 사용자 UI·조직·권한의 SLA가 아니다. 이미 정확한 대상의 Success + Create가 있으면 계정 생성 때문에 다시 40분을 기다리지 않는다. GHES의 같은 계정·active·SSO와 필요한 팀 권한을 확인한다. 할당 전파 전 Not assigned라면 몇 분 후 범위와 로그를 재확인하며 반복 실행으로 덮지 않는다. F7 결과를 참고한다.

역할 변경을 강제하는 기능이 아니다

Microsoft는 on-demand 역할 프로비저닝 미지원을 명시한다. 따라서 Owner 후보의 계정 생성·매칭 시험과 실제 Owner 역할 검증을 분리한다. GHES가 지원하는 SCIM Owner 반영은 5.1의 관리자 제어·앱 역할·roles 매핑 조건을 충족한 정기 동기화의 실제 출력과 GHES Owner 목록으로 확인한다. on-demand 재실행·Owner 우회 부여로 해결하지 않는다.

5.8 Cloud 한정: 해시 이름·Suspended 계정의 판정

GHES 사용자명 규칙으로 전용하지 않는다

아래는 GitHub.com의 GHEC EMU에서 무작위·해시처럼 보이는 이름을 조사할 때의 조건부 판단 기준이다. GHES 사용자명이나 shortcode 규칙으로 적용하지 않는다. 실제 계정에서 <hash>_SHORTCODE와 Suspended가 함께 확인되면 SCIM deprovision 흔적일 수 있으나 이름만으로 soft/hard 또는 실행 주체를 판정할 수 없다.

Cloud에서 확인할 것해석경계
Enterprise settings → People → Suspended members정지된 managed user는 GitHub Enterprise 좌석을 소비하지 않음목록에 남아 있어도 활성 계정·소비 좌석이라는 뜻이 아니다.
Active이나 unaffiliated인 사용자어느 조직에도 속하지 않은 unaffiliated 사용자는 Enterprise 라이선스 비소비연결된 Visual Studio 번들 라이선스의 별도 소비는 예외로 확인한다. 조직·저장소 접근과 실제 청구 기준을 대조한다.
Soft deprovision + 같은 Entra Object IDexternalId·SCIM User ID 연결이 남아 동일 소스 객체로 복구 가능동일 UPN의 새 객체는 대체 불가. 원인 확인과 복귀 승인 후 IdP에서 처리하고 실제 접근을 재검증한다.
Hard deprovision연결 신원이 제거되어 기존 계정 복원 불가새 계정과 기존 기록을 합칠 수 없다. 진단 목적으로 삭제하거나 재생성하지 않는다.

목록 존재 ≠ 조직 멤버십 ≠ consumed Cloud licenses ≠ 설치된 GHES capacity다. Cloud 감사 로그의 user.rename·user.suspend·external_identity.deprovision을 같은 UTC 구간의 Cloud용 Entra Enterprise app Provisioning logs와 대조한다. GHES 앱 로그를 대신 사용하지 않는다. 앱 Object ID·Tenant URL·source Object ID·실제 요청 종류로 원천을 확인하기 전에는 계정 삭제·임의 이름 변경·앱 재할당을 하지 않는다. soft 복구 가능성이 곧 복귀 승인은 아니다.

공식 근거: Entra 초기·증분·범위·격리 · Entra on-demand·전파 지연·역할 제한 · Entra 로그·Change ID·Steps · 3.21 정확한 GHES Tenant URL · Cloud EMU 퇴사·복귀·감사 이벤트 · Cloud·Server 라이선스 소비 기준

공식 근거: 3.21 SCIM setup·Owner 옵션 · 3.21 기존 사용자 매칭 · 3.21 SCIM API·pagination · 3.21 단일 쓰기 원천·가용 좌석 · 3.21 신원·프로비저닝 오류 · 3.21 퇴사·복귀 · GHES 좌석 기준 · Entra 최신 provisioning UI · 3.17 릴리스 · 3.14 릴리스

공식 화면 예시: F1 할당 · F2 Provisioning Overview · F3 Scope·Properties · F4 로그 목록 · F5 Steps · F6 on-demand 선택 · F7 결과. 연결된 이미지는 공식 문서의 일반 예시이며 실제 환경의 실행 증거를 대신하지 않는다. UI 버전 차이는 실제 앱에서 확인한다.

진행 기준 / 완료 증거: 정확한 신원 매칭, Owner SSO·복구 계정 유지, soft 복귀 시험 후 대상 확대.

Phase 6조직·팀·저장소의 최소 권한

상세 참조 장 · STEP 07의 실행 순서·화면으로 돌아가기 →

담당: 조직 Owner·보안·개발 리드선행: 파일럿 SCIM 성공산출물: 조직 팀 매핑·샘플 저장소·권한 시험

6.1 조직·팀·저장소 권한 모델

대상 예시설정최소 권한 확인
example-orgOrganization Owner 최소 인원, Settings → Member privileges → Base permissions: Noneenterprise owner와 조직 Owner를 별도 관리한다. 일반 사용자로 private 접근을 시험한다.
example-developersEntra Security group ↔ 조직 팀, 저장소 Write앱 할당만으로 저장소 권한이 생기는 것은 아니다.
example-reviewers표시 가능한 조직 팀, 저장소 Write, CODEOWNERS검토자 팀도 명시적인 Write가 필요하다.
example-private-projectPrivate팀 소속자만 업무 접근. 조직 Owner 등 관리 권한 예외를 별도 기록
example-shared-libraryInternal일반 enterprise member의 공유 영역. 특정 프로젝트 격리 용도가 아니다.
None은 Internal을 숨기지 않는다

Base permissions=None은 조직의 기본 권한을 줄이는 설정이다. 다른 조직 소속을 포함한 일반 enterprise member의 Internal 읽기 권한을 차단하지 않는다. 어떤 조직에도 속하지 않은 사용자·outside collaborator는 구분한다. 민감 프로젝트는 Private로 만들고 실제 비관리자 두 명으로 허용·거부를 시험한다.

  1. 사용자 → 그룹 → 팀 연결

    Phase 5에서 사용자 생성, Security group 프로비저닝, 그룹 멤버 반영을 순서대로 확인한다. Enterprise settings → Identity provider에서 그룹을 읽어 확인한다. 조직 → Teams → New team에서 이름을 입력하고 Identity Provider Groups → Select Groups로 연결 후 Create team 한다. 사용자가 연결된 팀에 들어가면 조직 멤버가 자동 추가된다.

  2. 기존 팀 전환은 별도 승인

    기존 팀 첫 연결 전 수동 추가 멤버를 제거해야 한다. 팀 이름·권한을 복제한 파일럿 팀으로 먼저 시험하고, 기존 멤버·저장소 권한을 기록한 후 영향 승인 창에서 전환한다. 사용자 계정 삭제가 아니다. 연결된 팀은 부모·자식 팀으로 중첩할 수 없고 팀 maintainer 지정에도 제약이 있다. 연결 해제 시 다른 가입 경로가 없으면 조직에서도 제거될 수 있다.

  3. 저장소 접근 부여

    조직에 Private 샘플 저장소를 만들고 저장소 Settings → Collaborators and teams에서 조직 팀별 Read·Write·Maintain·Admin을 업무에 맞게 부여한다. IdP는 팀 멤버십을, GHES는 팀의 저장소 역할을 관리한다. 이 절차는 조직 팀 기준이다. Cloud Enterprise Teams의 UI·권한 모델을 GHES 3.21에 그대로 적용하지 않는다.

  4. 보호 규칙을 실제로 강제

    저장소의 main 대상 ruleset 또는 branch protection에서 PR 승인, 필요한 status checks, Require review from Code Owners와 우회 권한을 명시한다. CI가 실제 보고하는 check 이름을 선택한다. CODEOWNERS 파일만 추가하면 리뷰 요청은 생겨도 병합 차단이 자동 보장되지는 않는다. 미승인·실패 check PR로 병합 거부를 검증한다.

  5. 앱·외부 인력·토큰 정책

    조직 소유권 변경·외부 협업자 초대·저장소 생성 권한을 제한한다. 외부 인력은 회사의 IdP 객체·계약 종료·외부 식별자 정책에 따라 온보딩하고 GHES outside collaborator 동작을 확인한다. Cloud EMU의 일괄 외부 협업 제한을 전제하지 않는다. 일반 PAT 만료·최소 scope·SSO 연계 요구·앱 승인을 GHES 버전별로 확인한다. 내부 자동화는 지원되는 작업에 GitHub App의 선택 저장소·최소 permissions를 우선하고, SCIM classic PAT 예외와 분리한다.

6.2 개발자 온보딩 템플릿

README, 기여 절차, PR 템플릿, CI와 .github/CODEOWNERS를 샘플 저장소에 둔다. 아래 패턴은 base branch의 CODEOWNERS 내용 예시이며 팀은 visible·Write 조건을 만족해야 한다.

승인 후 변경 · 샘플 저장소의 .github/CODEOWNERS · text
* @example-org/example-reviewers
/.github/ @example-org/example-reviewers
판정: 파일 추가는 별도 승인된 PR로 수행하고 code-owner review 강제 규칙까지 연결한다.
로컬 세션·파일 · 파일럿 개발자 PC의 승인된 작업 디렉터리 · bash
git clone https://github.example.com/example-org/example-private-project.git
git -C example-private-project config user.name 'Example Developer'
git -C example-private-project config user.email 'developer@example.com'
git -C example-private-project remote -v
판정: clone은 로컬 파일을 생성한다. HTTPS 인증은 승인된 credential helper/보안 프롬프트를 사용하며 PAT를 URL에 넣지 않는다.

git config user.*는 커밋 표시 정보이지 로그인·SSO 설정이 아니다. Git용 SSH 공개키는 개인 GitHub 계정에 등록하며 관리 Console의 SSH 122 키와 분리한다. Cloud의 토큰 SSO 승인 UI가 동일하다고 가정하지 말고 GHES 문서·현재 사용자 설정을 확인한다.

조회 · 승인된 일반 파일럿 사용자 PC · bash
git ls-remote https://github.example.com/example-org/example-private-project.git HEAD
판정: 허용 사용자는 HEAD를 읽고, 미허용 사용자는 읽지 못한다. 관리자 토큰이나 공유 credential로 대신 시험하지 않는다.

6.3 권한 수용 시험

시험 주체동작완료 증거
팀 멤버 일반 계정본인 SAML 로그인 → Private 웹 열람 → 본인 Git 인증으로 읽기세 경로 각각의 실제 계정·성공 시각
다른 조직의 일반 계정Private 거부 / Internal 읽기기본 None과 Internal 가시성의 차이를 입증
검토 없는 작성자미승인 PR·실패 check의 병합 시도규칙이 차단하며 관리자 우회가 시험에 섞이지 않음
그룹에서 제거된 파일럿동기화 후 팀·저장소 접근 확인직접 collaborator·다른 팀·조직 기본권한 잔존 조사
복귀 파일럿재할당 후 팀·조직·저장소 권한 확인SCIM active만 보고 권한 복구를 단정하지 않음

감사 로그와 분기별 Owner·앱 설치·토큰·SSH 키 검토 책임자를 정한다. GHES에서 제공되는 보안 정책과 라이선스를 확인하며 Cloud 전용 AI Controls가 보편적으로 존재한다고 쓰지 않는다. AI 기능은 Copilot 범위에서 별도로 검토한다.

공식 근거: 3.21 IdP 그룹과 조직 팀 · 3.21 저장소 가시성 · 3.21 CODEOWNERS 강제 조건 · 3.21 보호 브랜치

진행 기준 / 완료 증거: 일반 사용자의 Private 허용/거부, Internal 범위, PR 차단·그룹 제거 영향 검증.

Phase 7GitHub Connect와 라이선스 동기화

상세 참조 장 · STEP 08의 실행 순서·화면으로 돌아가기 →

담당: GHES·Cloud Owner·구매·개인정보 담당선행: 계약 자격·egress·전송 승인산출물: 연결 대상·선택 기능·사용량 대조

GitHub Connect는 GHES와 Cloud를 제한된 기능으로 연결한다. 사용자 프로비저닝이나 저장소 마이그레이션이 아니다. Cloud 계정이 자동 생성되지 않고 설치된 GHES 라이선스의 좌석 수도 자동 증가하지 않는다.

라이선스: 권한 파일과 사용량 보고는 반대 방향 동일한 로컬 Excalidraw 도형 데이터로 생성한 설명용 SVG. 편집기 내보내기가 아니며 HTML의 Clawpilot 테마를 상속합니다. 라이선스: 권한 파일과 사용량 보고는 반대 방향 파일 유효성, 허용 좌석 수, 실제 잔여 용량은 서로 다른 확인 항목 권한 공급 ① · PAYG / 계약 조건 확인 GHEC PAYG 소비된 GHE 좌석 기준 GHES 권한 파일 확인 라이선스 키 생성 파일 다운로드 GHES에 업로드 좌석 상한·유효기간 서버에서 확인 권한 공급 ② · 볼륨 계약 영업 / 볼륨 계약 라이선스 파일 수령 GHES에 업로드 계약 좌석 상한 적용 PAYG와 별도 계약 경로 사용량 보고 · 권한 파일 공급과 반대 방향 GHEC 집계·청구 이메일 기반 중복 조정 계약별 적용 확인 GitHub Connect 사용량 보고 GHES 활성 사용자 사용량 혼동하지 말아야 할 항목 무소속 Cloud 계정 ≠ 소비된 GHE 좌석 · 모든 GHES 사용자에게 Cloud 계정을 요구한다는 의미 아님 Copilot은 별도 라이선스 · 유효한 라이선스 파일 ≠ 현재 남은 좌석 수 실제 자격·청구·중복 조정은 계약과 계정 연결 조건 확인 · 이 도식은 좌석 구매량을 보장하지 않음 설명용 개념도 · 실제 화면이나 고객 환경이 아님 · 연결은 주요 논리 흐름만 표시
설명용 개념도. 라이선스 파일의 발급·적용과 GHES 사용량의 Cloud 보고 방향을 구분합니다. 보고 동기화가 계정이나 기존 파일 용량을 자동 갱신하지 않습니다.

7.1 연결 전 승인 입력

입력예시 / 요구 조건판정
연결 대상github.example.com ↔ 승인된 GitHub.com enterprise다른 Cloud enterprise에 잘못 연결하지 않도록 이름·소유자 확인
권한GHES site administrator / enterprise owner와 Cloud enterprise owner양쪽 브라우저 로그인, 관리 권한·다중 계정 혼동 방지
계약 자격3.21 GitHub.com Connect 문서: invoiced enterprise무료 trial·credit card 계정 제외 문구 확인. 구매 방식만으로 추정 금지
네트워크GHES → github.com, api.github.com, uploads.github.com, 승인된 HTTPS egress프록시·DNS·TLS 신뢰, Cloud IP allow list에 GHES 출구 IP 허용. SCIM 수신 경로와 분리
개인정보 승인user ID·email 및 기능별 추가 데이터전송 목적·수신 Cloud·보존·접근권한 검토
PAYG와 Connect 자격의 문서 차이

사용량 기반 과금 문서는 Cloud/Server 병용과 GitHub Connect를 설명하지만, 3.21 Connect 활성화 문서는 invoiced 요건과 trial·credit-card 제외를 별도로 명시한다. 모든 PAYG 계정이 가능하거나 불가능하다고 단정하지 말고 실제 enterprise의 자격을 GitHub Sales/Support에 확인한 뒤 연결한다.

  1. 브라우저 연결

    GHES와 GitHub.com에 각각 로그인한다. GHES 프로필 → Enterprise settings → GitHub Connect → Enable GitHub Connect. Cloud 로그인·승인 흐름에서 대상 enterprise를 선택하고 해당 항목의 Connect를 누른다. Choose enterprise 화면의 대상 이름과 약관을 검토한다. Management Console에서 SCIM 토큰을 붙이는 절차가 아니다.

  2. 원하는 기능만 선택

    GHES GitHub Connect 화면의 License sync → Enable을 별도로 선택한다. 필요할 때만 GitHub.com actions, Dependabot alerts, unified search/contributions 등 현재 버전에서 지원하는 기능을 승인한다. Actions 실행·runner와 보안 기능의 GHAS/Code Security/Secret Protection 자격은 별도이다. Connect 하나로 전부 활성화되지 않는다.

  3. 첫 동기화와 증거 수집

    자동 사용자 라이선스 동기화는 GHES 사용량을 GHEC에 보내는 주 단위 작업이며 키 갱신이 아니다. 즉시 외부 데이터 전송을 승인했다면 GHES Enterprise settings → Settings → License(또는 Licensing) → License sync → Sync now를 사용한다. 이는 단순 조회가 아니라 데이터 전송이다. Cloud Billing and licensing → Licensing에서 해당 Server source·마지막 동기화 시각·상태를 읽어 확인한다.

  4. 불일치 분석

    GHES active·suspended 사용자, GHES 기본 이메일, Cloud 신원·검증 이메일, 중복 제거 결과를 대조한다. Cloud 사용량 화면의 GitHub Connect server usage synced / never synced / Server usage uploaded 구분과 시각을 남긴다. 네트워크 실패·잘못된 연결 대상·이메일 불일치를 구분하고 무작정 재연결하지 않는다.

7.2 전송·중복 제거·비용은 별도 판정

구분실제 의미주의
데이터 흐름GHES → Cloud로 사용자 ID·이메일 주소, 보안 제품 라이선스 소비 여부; 연결 메타데이터도 전송익명 인원수만 보내는 기능이 아니다. 상세 Connect 데이터 표를 개인정보 검토 기준으로 삼는다.
전송하지 않는 항목Connect 자체가 repository·issue·pull request를 Cloud로 자동 전송하지 않음추가 Actions·앱·외부 서비스의 데이터 흐름까지 없다는 뜻은 아니다.
중복 제거GHES 기본 이메일을 Cloud SAML/SCIM 신원 속성에 먼저 매칭, 미일치 시 검증된 Cloud 이메일 비교username 동일만으로 보장하지 않는다. 이메일 변경·별칭·여러 Server source를 확인한다.
라이선스 수치Billing and licensing → Licensing의 consumed Cloud licenses와 병용 총량을 구분metered Server 라이선스 생성에는 Cloud 소비 수를 사용한다. People → Members의 결합 Total consumed를 그대로 넣지 않는다.
설치 라이선스현재 GHES License 화면의 파일·유효기간·좌석과 계약 대조Connect 동기화가 라이선스 파일 갱신·증설을 대신하지 않는다.
추가 비용Copilot, Security 제품, Actions·Packages 사용량, blob 저장소·runner·백업·인프라기본 Enterprise 좌석의 중복 제거가 모든 제품·인프라 비용의 면제를 의미하지 않는다.
조회 · 승인된 GHES와 동일 egress·프록시 경로의 진단 환경 · bash
curl --head --silent --show-error --connect-timeout 10 https://api.github.com
판정: TLS·HTTP 도달성의 일부 증거만 된다. 관리자 노트북의 성공만으로 appliance 연결·계약 자격·라이선스 sync 성공을 주장하지 않는다.
오프라인 대안과 Copilot 경계

자동 연결이 불가능하면 공식 절차의 GHES License → Export license usage와 Cloud Licensing → Add server usage를 승인된 별도 수동 전송으로 검토한다. 파일에도 사용자 데이터가 있으므로 일반 공유 폴더에 두지 않는다. Connect는 GHES 호스팅 저장소에서 Copilot cloud agent의 issue/PR 작업을 가능하게 만드는 스위치가 아니다. Cloud agent와 로컬 IDE 지원을 구분하고 Copilot 기능·호스팅 조건을 확인한다.

7.3 세 가지 동기화 시계와 라이선스 파일 적용을 구분한다

시계주기·시간의 의미완료 증거 / 잘못된 해석
① Entra 자동 프로비저닝: initial / incremental처음에는 전체 구성 범위 평가, 이후 변경분 증분. 약 40분은 일반 안내로 앱별 문서·현재 job 주기를 확인대상별 Action·Status·Target ID·GHES 상태로 판정한다. 모든 앱의 고정 주기나 사용자별 SLA가 아니다.
② Entra Provision on demand승인된 사용자 한 명의 실제 쓰기. 통상 30초 미만이라는 Microsoft 안내Steps·실제 action·대상 상태 확인. 새 할당 전파 수 분과 UI·조직 권한 반영은 별도이며 완료 시간을 보장하지 않는다.
③ GitHub Connect license usage syncGHES → GHEC 사용량 자동 전송은 매주. 승인 후 Sync now로 별도 실행 가능Cloud의 해당 Server source·마지막 성공 시각·상태 확인. SCIM 사용자 생성도 GHES 키 자동 갱신도 아니다.

별도 파일 적용 시간: 새 GHES 라이선스 키를 승인 후 Upload하면 백그라운드로 적용되며 화면 반영에 몇 분 걸릴 수 있다. 이는 위 세 동기화 주기와 다르다. 키 만료일도 별도로 추적한다. metered 방식의 생성 키는 문서상 1년 유효하며 현재 파일의 실제 만료일·갱신 알림을 확인한다. weekly sync나 사용자 증분이 만료를 연장하지 않는다.

7.4 주간 전송의 성공은 토글이 아니라 상태로 확인한다

License sync의 Enable은 설정 증거일 뿐 전송 성공 증거가 아니다. GHES Enterprise settings → Settings → License / Licensing → License sync → Sync now는 사용자 ID·이메일 등 사용량 데이터의 외부 전송이므로 목적·수신 enterprise·전송 범위 승인 후 실행한다. 실행 전후 Cloud Billing and licensing → Licensing의 해당 Server source, last sync, 성공·실패 또는 never synced 상태를 기록한다. 수동 실행 역시 GHES capacity를 늘리거나 라이선스 키를 재발급하지 않는다.

정각·첫 즉시 실행·사용자 cron을 약속하지 않는다

license sync 문서는 주간 자동 전송과 수동 Sync now를 설명하지만 고정 분 단위 실행 시각, Enable 직후 첫 실행의 즉시 완료, 사용자가 지정하는 cron을 보장하지 않는다. About GitHub Connect의 ‘활성화한 요일·대략적 시각부터 매주’ 문구는 연결 메타데이터 동기화 설명이다. 이를 license usage job의 신뢰할 수 있는 실행·완료 SLA로 전용하지 않는다.

7.5 신규 사용자와 키 재발급은 조건부로 연결한다

  1. 설치 capacity·만료·소비량을 먼저 읽기

    신규 사용자 한 명마다 무조건 키를 재생성하지 않는다. 현재 GHES License 화면의 설치 좌석·사용량·만료, Cloud의 consumed Cloud licenses, 계약·과금 방식을 각각 대조한다. metered Server 키는 생성 시점의 consumed Cloud licenses를 기준으로 capacity가 정해지므로 Cloud 계정 목록 수나 결합 Total consumed를 대신 넣지 않는다.

  2. 부족·갱신 필요가 확인된 경우에만 파일 변경 승인

    현재 설치 capacity가 필요한 사용량에 부족하거나 갱신이 필요한 경우, 자격·계약·다운로드 가능한 새 capacity를 확인한 뒤 승인받아 새 키 생성·다운로드·GHES 업로드를 수행한다. Cloud Licensing의 Generate new license 안내는 metered Cloud 소비 증가 또는 만료 30일 이내 등의 조건으로 나타난다. 업로드 뒤 백그라운드 반영과 실제 좌석·만료일을 다시 확인한다. Cloud에서 먼저 모든 사람을 만들어야만 GHES SCIM 생성이 된다는 보편적 순서로 바꾸지 않는다.

문서상 가용 좌석 불필요와 실제 오류의 차이는 Support 확인

2026-09-21 확인한 GHES 3.21 SCIM REST how-to는 ‘enterprise doesn’t require an available license to provision a new user account’라고 명시한다. 실제 요청에서 out-of-seats 오류가 발생하면 HTTP 상태와 응답 본문을 로그로 확인한다. 문서와 관측의 차이를 지우거나 확인된 제품 버그로 단정하지 않는다. 정확한 3.21 패치·endpoint·UTC·request ID·오류 본문·설치 라이선스 capacity/만료·실사용량·과금 방식으로 Support에 해당 요청의 제한 조건과 문서 적용 범위를 질문한다. SCIM 계정 생성, 로그인 시 좌석 소비, Cloud 소비, 설치 키의 수용량을 구분하며 계정 삭제·역할 승격·전체 재시작으로 우회하지 않는다.

7.6 운영자 인수인계 체크리스트

완료·실패·미확인 항목을 구분하고 각 증거 위치, 담당자, 승인된 다음 조치를 인계한다. 요약 상태만으로 계정·권한·연결의 종단 간 검증을 대신하지 않는다.

점검 항목인계할 증거완료·중단 기준
앱 할당·프로비저닝정확한 앱·사용자 ID, 할당 이후 UTC 구간, job 상태와 대상별 Steps로그 0건은 서버 미호출이나 실패의 증명이 아니다. 범위·보존·필터를 확인하며 전체 sync를 재시작하지 않는다.
계정·로그인·역할Target ID·externalId·active, 일반 계정 SSO, 정기 동기화 roles와 실제 GHES Owneron-demand Success만으로 역할을 판정하지 않는다. 복구 계정·PAT 유지와 조직·저장소 권한을 별도 검증한다.
Connect 사용량 전송해당 Server source·마지막 성공 시각·상태·수신 Cloud와 이메일 매칭주간 license sync는 사용량 전송이지 계정 생성이나 설치 키·quota 갱신이 아니다.
임시 광범위 outbound승인 범위·기한·담당자, 최소 목적지·프록시 재시험·원복 계획임시 성공은 운영 완료가 아니다. SCIM inbound와 구분하고 검증 후 임시 규칙을 회수한다.
설치 키와 사용량설치 capacity·잔여 좌석·만료일·Cloud 소비·계약, 변경 시 전후 값여유가 충분하면 사용자마다 재발급하지 않는다. 증설·갱신 필요가 확인된 경우만 승인 후 파일을 변경한다.

공식 근거: Entra 주기·상태 · Entra on-demand 시간·제한 · 3.21 연결 메타데이터의 주간 시각 · 3.21 키 생성 조건·metered capacity·유효기간 · 3.21 키 업로드·백그라운드 적용 · 3.21 SCIM 생성과 가용 라이선스

공식 근거: 3.21 GitHub.com Connect 자격·UI · 3.21 기능·전송 데이터 · 3.21 자동 license sync · 3.21 수동 실행·파일 대안 · 3.21 Cloud/Server 병용 · 3.21 사용량 기반 결제 · 3.21 이메일 중복 제거 · Cloud 현재 사용량 UI · Copilot 현재 제품 범위 · Cloud agent 현재 호스팅 조건

진행 기준 / 완료 증거: 마지막 sync 시각·source·이메일 매칭과 설치 라이선스를 대조하고 비용·Copilot 범위를 분리.

Phase 8Actions 제어 서비스와 외부 저장소

상세 참조 장 · STEP 09의 실행 순서·화면으로 돌아가기 →

담당: GHES·Azure·Entra·보안 담당선행: TLS·DNS·라이선스·용량·백업산출물: 인증 선택표·경로표·쓰기 테스트·구성 적용 기록

범위·실행 원칙 · 2026-09-19 검토

기준은 GHES 3.21이다. 신규 3.22는 아래 차이 표시와 해당 버전 문서를 함께 확인한다. 이 문서는 공개 자료로 작성한 일반 절차이며 실제 환경에 접속하거나 검증한 결과가 아니다. github.example.com, storageexample, testorg는 예시다. 조회도 사전 권한이 필요하며, 변경·테스트·저장·비용 발생은 승인된 작업창에서만 수행한다. 고객 정보, 토큰, 키, 연결 문자열을 문서·채팅·로그에 넣지 않는다.

8.1 구성과 용량을 먼저 결정한다

Actions: 실행 호스트, 저장소 설정, 인증을 분리 동일한 로컬 Excalidraw 도형 데이터로 생성한 설명용 SVG. 편집기 내보내기가 아니며 HTML의 Clawpilot 테마를 상속합니다. Actions: 실행 호스트, 저장소 설정, 인증을 분리 전용 Runner는 GHES 어플라이언스 밖에 배치 · 선은 전체 방화벽 매트릭스가 아님 실행 경로 GHES Actions 서비스 작업·저장소 제공 결과·로그 관리 전용 Runner 호스트 작업 pull · checkout 워크플로 실행 Blob Storage 아티팩트 송수신 직접 경로: 조건부 443 / pull 구성별 443 GHES 아티팩트: upload-artifact / download-artifact @v3-node20 사용 · v4 아님 저장소 설정 · 두 인증 방식 중 지원 구성 선택 GHES Actions 서비스 외부 객체 저장소 설정 저장소에 HTTPS 연결 Azure Blob 계정·컨테이너 권한·접근 검증 Shared Key 자격 증명 또는 OIDC 앱 연합: Tenant / Client / scope GHES → Blob 경로와 Runner → Blob 경로는 각각 확인 · Runner 직접 통신을 모든 구성에 일반화하지 않음 OIDC 선택 시 · 인증 서비스가 발급자 정보를 조회할 수 있어야 함 Entra 인증 서비스 OIDC 서명 검증 공개 메타데이터 조회 GHES OIDC 발급자 Discovery / JWKS 공개 도달성 필요 인증 서비스 → GHES 443 issuer: https://HOST/_services/token · subject: HOST HOST는 GHES 호스트명 자리표시자 · 예: github.example.com · SCIM 경로와 별개 앱 연합 자격 증명의 issuer / subject / audience 및 저장소 권한은 실제 버전·공급자 설정으로 검증 OIDC 공개 조회 요건이 충족되지 않으면 해당 방식 사용을 가정하지 말고 승인된 대안을 검토 설명용 개념도 · 실제 화면이나 고객 환경이 아님 · 연결은 주요 논리 흐름만 표시
설명용 개념도. Actions 서비스·자체 호스팅 Runner·외부 Storage의 역할과 인증 경계. OIDC와 credential 방식을 혼합해 진단하지 않습니다.
대상설계·입력확인 기준
GHES applianceActions 제어 서비스. runner나 Node.js 빌드 도구를 appliance에 설치하지 않는다.GHES에서는 GitHub-hosted runner를 사용할 수 없다. 별도 self-hosted runner가 필요하다.
CPU·메모리Actions 최소 8 vCPU / 64 GB. Azure 설치 문서의 사용자 규모별 기본 자원에서 CPU·메모리 각각 최소 25% 추가도 반영한다.두 조건을 모두 충족하는 VM을 선정한다. 연결 runner 수는 작업 길이·artifact·저장소 부하에 따라 달라지며 보장 수치가 아니다. pilot의 queue·CPU·메모리·I/O로 조정한다.
외부 객체 저장소Azure Blob 또는 Amazon S3 등 공식 지원 공급자 중 하나. 이 절차는 Azure Blob 기준.로그·cache·artifact는 외부 저장소, workflow 소스·기타 메타데이터는 GHES에 남는다. 외부 저장소로 root/data 디스크 용량을 대체할 수 없다.
Azure 계정 종류신규 권장 예: Standard / StorageV2(GPv2). 지원 대안: Premium / BlockBlobStorage.Standard GPv1/GPv2와 Premium BlockBlobStorage를 구분한다. Premium general-purpose 계정은 Actions에 미지원이다. SKU만 보지 말고 kind도 확인한다.
운영 승인저장소·네트워크·Entra·GHES 담당과 비밀 관리자 지정. 변경 전 백업·복구 및 키 회전 계획.기존 account의 firewall, Private Endpoint(PE), DNS, 보존 정책을 읽고 공유 서비스 영향부터 확인한다.

8.2 인증 분기와 UI 입력값

모드·화면입력주의
Credentials-based비밀 관리자가 승인된 경로로 전달한 Azure account connection string을 Management Console의 비밀 입력란에만 입력.Client ID와 Tenant ID만으로 인증되지 않는다. account key 기반 연결 문자열에는 Shared Key 허용이 필요하다. 키 조회 명령·인라인 키·디버그 출력은 사용하지 않는다.
OIDC: App registrations → New registration저장소 인증용 Entra 앱을 생성하고 Application (client) ID / Directory (tenant) ID 기록.기존 SAML/SCIM 앱 재사용을 기본값으로 삼지 않는다. 앱 소유 tenant, storage subscription tenant, 청구/Billing tenant가 같은지 별도로 확인한다.
OIDC: Certificates & secrets → Federated credentials → Add credentialOther issuer; Issuer = https://github.example.com/_services/token; Subject identifier = github.example.com; Name = ghes-actions-storage.Subject에는 https:// 또는 repo:를 붙이지 않는다. workflow의 token.actions… issuer / repo subject가 아닌 GHES 저장소 서비스 신뢰다. Audience는 공식 절차·Portal 기본값을 확인해 일치시킨다.
OIDC: Storage → Access control (IAM)Add role assignment → Storage Blob Data Owner → Members에서 해당 앱의 service principal 선택.GitHub 절차는 저장소 account 범위다. Subscription Owner를 부여하지 않는다. Client ID, 앱 object ID, Enterprise applications의 SP object ID는 서로 다른 값이다.
Management Console → ActionsEnable GitHub Actions → Artifact & Log Storage → Azure Blob Storage → Setup → Authentication 선택.OIDC는 Entra ID tenant ID / client ID / Azure storage account name / Azure blob endpoint suffix 네 필드가 필요하다.
OIDC: account / suffixstorageexample / core.windows.netsuffix에 https://, account 이름, .blob 또는 전체 URL을 넣지 않는다. 국가별 Azure는 Storage → Endpoints의 실제 suffix를 사용한다.
OIDC의 공개 경로는 필수지만 GHES 전체 공개는 아니다

클라우드 인증 서비스가 아래 두 경로의 public DNS와 신뢰 가능한 TLS에 접근할 수 있어야 한다. 내부 PC에서 열리는 것만으로 충분하지 않다. 공개 허용은 보안 검토한 metadata/JWKS 경로로 제한하고 다른 경로를 무조건 개방하지 않는다. 이 조건이 금지되면 OIDC 구성을 중단하고 정책상 승인된 Shared Key/연결 문자열 대안을 검토한다. Shared Key 금지 정책을 임의로 해제하지 않는다.

조회 · 네트워크 설계표 · text
https://github.example.com/_services/token/.well-known/openid-configuration
https://github.example.com/_services/token/.well-known/jwks
판정: 두 URL의 외부 인증 서비스 접근·TLS 검증 가능 여부를 승인 기록으로 남긴다.

8.3 비밀을 출력하지 않는 사전 조회

아래 Azure CLI는 이미 인증된 승인 세션에서 실행한다. 계정 전환이 필요하면 현재 출력을 확인한 뒤 별도 승인으로 로그인한다. APP_TENANT_ID, STORAGE_TENANT_ID, SUBSCRIPTION_ID, APP_CLIENT_ID, STORAGE_SP_OBJECT_ID는 담당자가 확인한 값이며 비밀번호가 아니다. 연결 문자열은 이 변수 목록에 포함하지 않는다.

조회 · 승인된 관리자 PC · bash
az account show --query "{subscription:id,tenant:tenantId,state:state}" -o json
az storage account show --resource-group rg-ghes-storage --name storageexample --query "{id:id,kind:kind,sku:sku.name,location:location,httpsOnly:enableHttpsTrafficOnly,minTLS:minimumTlsVersion,sharedKey:allowSharedKeyAccess,publicNetwork:publicNetworkAccess,firewallDefault:networkRuleSet.defaultAction,blobEndpoint:primaryEndpoints.blob}" -o json
판정: 대상 subscription/tenant와 kind/SKU, Shared Key 및 네트워크 정책 확인. sharedKey=null은 false와 같다고 해석하지 않고 유효 기본 정책을 확인한다. 이 조회는 Blob 쓰기 권한 증명이 아니다.
로컬 세션·파일 · 승인된 관리자 PC · bash
az login --tenant "$APP_TENANT_ID" --allow-no-subscriptions --output none
판정: OIDC 앱 소유 tenant 조사에 한해 승인 후 로그인. 로컬 인증 캐시가 바뀐다. 범용 tenant 탐색을 하지 않는다.

OIDC를 선택한 경우에만 다음 앱/Federated credential 조회를 수행한다. 앱 소유 tenant에서 읽기 권한이 있어야 한다. Credentials-based의 403을 고친다고 무관한 앱에 RBAC를 추가하지 않는다.

조회 · 승인된 관리자 PC · bash
az ad app show --id "$APP_CLIENT_ID" --query "{clientId:appId,appObjectId:id,displayName:displayName}" -o json
APP_OBJECT_ID=$(az ad app show --id "$APP_CLIENT_ID" --query id -o tsv) &&
test -n "$APP_OBJECT_ID" &&
az ad app federated-credential list --id "$APP_OBJECT_ID" --query "[].{name:name,issuer:issuer,subject:subject,audiences:audiences}" -o json
판정: issuer/subject/audience를 대조한다. 앱 등록 object ID를 명시적으로 사용한다. 403/권한 거부는 항목 없음이 아니다. 앱 소유 tenant가 아니면 여기서 멈춘다.
로컬 세션·파일 · 승인된 관리자 PC · bash
az login --tenant "$STORAGE_TENANT_ID" --output none
az account set --subscription "$SUBSCRIPTION_ID"
판정: 저장소 tenant/구독 조회용 별도 승인. 앞의 앱 소유 tenant 세션과 혼동하지 않는다.
조회 · 승인된 관리자 PC · bash
az ad sp show --id "$APP_CLIENT_ID" --query "{clientId:appId,spObjectId:id,appOwnerTenant:appOwnerOrganizationId}" -o json
STORAGE_SCOPE=$(az storage account show -g rg-ghes-storage -n storageexample --query id -o tsv) &&
test -n "$STORAGE_SCOPE" &&
az role assignment list --scope "$STORAGE_SCOPE" --assignee-object-id "$STORAGE_SP_OBJECT_ID" --include-inherited --fill-principal-name false --query "[].{role:roleDefinitionName,scope:scope,principalId:principalId}" -o json
판정: STORAGE_SP_OBJECT_ID는 위 SP 조회로 확인한 값이다. 저장소 범위·해당 SP만 조사한다. 다른 tenant의 동명 앱, app object ID와 혼동하면 중단하고 담당자와 매핑을 수정한다.

8.4 경로 확인 → 저장소 쓰기 테스트 → 설정 적용

  1. 경로를 각각 승인한다

    GHES → Blob, runner → GHES hostname/API 및 필요한 Blob 경로, Entra → OIDC metadata/JWKS를 별도 항목으로 검토한다. Entra SCIM → GHES의 inbound 성공은 Blob outbound 성공 증거가 아니다. PE의 private DNS zone·VNet 연결·실제 서비스의 DNS 응답·출구 NAT/firewall을 확인한다. HTTP proxy 제외 목록의 .localhost, 127.0.0.1, ::1과 내부 저장소 경로도 공식 문서에 맞춘다.

  2. 연결만 확인한다

    승인된 GHES 관리 셸에서 아래 무인증 curl을 실행한다. PC의 같은 명령은 보조 자료일 뿐이다. 인증 없는 400/403은 HTTP 도달 가능성을 보여도 실제 GHES 서비스의 proxy 환경이나 읽기·쓰기 권한을 증명하지 않는다. TLS 오류를 -k로 우회하지 않는다.

  3. Test storage settings — 변경 승인 필요

    Management Console에서 승인된 테스트 범위에 대해 실행한다. create/upload/delete를 포함하는 쓰기 검증으로 취급한다. 읽기 전용 점검으로 분류하지 않는다. 테스트 시각과 성공/오류 코드만 기록하고 잔여 테스트 객체 및 정리 결과를 저장소 담당자가 확인한다.

  4. Save settings — 서비스 재시작 가능

    테스트 통과 후 공지된 작업창에서 저장한다. configuration run 종료까지 기다리고 진행 화면·구성 로그의 성공/실패 단계·시각을 기록한다. 진행 중 재저장하거나 ghe-config-apply를 중복 실행하지 않는다. 실패 시 원인 분석과 승인된 복구 절차로 돌아가며 저장소를 임의 교체하지 않는다.

조회 · 승인된 GHES 관리 셸 · bash
curl --silent --show-error --connect-timeout 10 --max-time 20 --output /dev/null --write-out "HTTP %{http_code}\n" https://storageexample.blob.core.windows.net/
ghe-config core.github-hostname
판정: curl은 인증/권한 검증이 아니다. ghe-config는 이 단일 비밀 아닌 키만 조회한다. 전체 설정 목록, secrets 값, connection string, Authorization header는 출력하지 않는다.

구성 진행은 Management Console의 진행/로그 화면을 우선 사용한다. 추가 로그는 해당 버전의 관리 유틸리티 도움말과 공식 지원 절차로 범위를 좁혀 확인한다. 원본 전체 로그를 공유하지 말고 configuration run 단계·UTC 시각·마스킹된 오류만 전달한다.

8.5 403을 인증·권한·네트워크로 나누어 조사한다

오류/현상먼저 볼 것승인 후 조치
AuthenticationFailed선택한 인증 모드, account 불일치, 키 회전·문자열 손상·시간 오차. OIDC이면 교환 오류와 issuer/subject/audience/TLS.비밀 관리자가 일치 여부만 확인한다. 키를 로그에 복사하거나 --debug를 켜지 않는다. SAS를 임의 대체 인증으로 넣지 않는다.
KeyBasedAuthenticationNotPermittedCredentials-based 요청인데 Shared Key가 정책상 금지되었는가?Actions는 공개 metadata/JWKS 조건이 충족되면 OIDC 검토. Shared Key 변경은 보안 승인 필요. Client/Tenant 입력만 추가해 해결하려 하지 않는다.
AuthorizationPermissionMismatch실제 OAuth SP·Data Owner·scope·전파 시간·필요한 write/delete 동작.OIDC 선택 확인 후 정확한 SP에 공식 역할 적용. ARM Reader/Contributor와 Blob 데이터 역할은 다르다. 광범위 Owner로 우회하지 않는다.
AuthorizationFailureStorage firewall, publicNetworkAccess, PE/DNS, GHES/runner 출구와 허용망.실패 경로만 수정한다. SCIM 연결 결과나 관리자 PC 성공으로 통과 처리하지 않는다.
timeout / TLS / 로그 없음DNS·라우팅·proxy·인증서 체인, 진단 로그 사전 활성화·수집 지연.TLS 검증을 유지한다. 로그 미수집은 요청 미발생의 증명이 아니다.

StorageBlobLogs는 Blob 진단 설정이 Log Analytics로 수집 중일 때만 조회 가능하다. 진단 설정 활성화는 별도 변경·비용 승인이다. 아래는 실패 재현 직후 15분 범위 예시이며, URI/SAS/인증 hash는 출력하지 않는다. 필요한 식별자는 내부 제한 기록에서만 상관 분석한다.

조회 · 승인된 Log Analytics workspace · kusto
StorageBlobLogs
| where TimeGenerated > ago(15m)
| where AccountName == "storageexample"
| project TimeGenerated, OperationName, StatusCode, StatusText,
    AuthenticationType = column_ifexists("AuthenticationType", ""),
    CorrelationId = column_ifexists("CorrelationId", ""),
    ClientRequestId = column_ifexists("ClientRequestId", "")
| order by TimeGenerated desc
| take 50
판정: 요청 시각·동작·인증 유형·상태로 분류한다. 존재를 가정한 RequestId 열을 사용하지 않는다. 결과 0건을 정상 판정으로 쓰지 않는다.
신규 3.22 차이 확인

공식 3.21/3.22 Azure Actions 문서 모두 OIDC와 connection string 두 방식을 안내한다. 3.22라는 이유로 필드·저장소 종류·공개 metadata 요구가 사라지지 않는다. 설치할 patch의 릴리스 노트, runner와 action runtime 호환성을 다시 승인한다.

공식 근거: Actions 개요·최소 자원 · Azure 설치·25% 증설 · 3.21 Azure 인증 · 3.22 Azure 인증 · 관리 명령 · Azure 403 · Federated credential CLI · StorageBlobLogs 스키마

진행 기준 / 완료 증거: 인증 방식/ID 매핑/용량 검토 완료 → 승인된 저장소 쓰기 테스트 통과 → configuration run 성공. 여기까지는 실행 엔진 준비이며, Phase 9의 실제 workflow·artifact 왕복까지 통과해야 서비스 완료다.

Phase 9격리 runner와 workflow 종단 검증

상세 참조 장 · STEP 10의 실행 순서·화면으로 돌아가기 →

담당: Runner 운영·조직 관리자·pilot 개발자선행: Phase 8 적용 성공·private 테스트 저장소산출물: runner 그룹·실행 URL·artifact 비교·접근 차단 증거

9.1 appliance와 격리한 실행 VM을 준비한다

입력/화면설정 예검증
전용 VM·리소스 그룹rg-ghes-runners의 Linux x64 VM, 전용 OS 서비스 계정. GHES appliance와 분리.신뢰 수준·팀·운영/비운영별 VM/네트워크/runner group 격리. VM 관리 ID에 운영 subscription 권한을 주지 않는다.
네트워크runner outbound TCP 443 → github.example.com, api.github.example.com 및 구성에 필요한 artifact/Blob host.DNS·CNAME·TLS CA·proxy·NO_PROXY·시간 동기화 확인. inbound runner 포트를 인터넷에 열지 않는다. 인터넷 action 접근은 허용한 공급 방식에만 필요하다.
Organization Settings → Actions → Runner groupspilot-linux 그룹, Selected repositories = testorg/ghes-smoke.레이블은 라우팅 조건이지 보안 경계가 아니다. 그룹의 repository allowlist와 workflow 정책을 함께 제한한다.
Settings → Actions → Runners → New self-hosted runnerOS = Linux, Architecture = x64; 이름 = pilot-linux-01; label = ghes-pilot.선택한 GHES 버전 UI가 제공하는 다운로드·checksum·config 명령을 사용한다. 인터넷 최신 runner를 무조건 설치하지 않는다.
Actions 공급기본 bundled action / 승인된 GitHub.com 자동 접근 / 수동 동기화 중 하나.checkout@v4, upload-artifact@v3-node20, download-artifact@v3-node20의 실제 ref와 action.yml을 확인한다. 미러 경로가 다르면 uses도 바꾼다.
  1. 생성된 설치 명령을 실행한다 — 변경

    VM의 전용 작업 디렉터리에서 UI 명령을 순서대로 복사한다. 일반 OS 계정으로 압축 해제·config를 실행한다. 등록 URL은 조직 URL이어야 한다. UI의 등록 token은 1시간 만료되는 비밀이며 PAT와 다르다. token을 문서에 전사하지 않고 로그·셸 추적을 끈 승인 세션에서 사용한다. 만료되면 UI에서 다시 발급한다.

  2. 그룹·레이블을 확인한다

    등록 단계에서 pilot-linux 그룹과 ghes-pilot 레이블을 선택한다. 기본 self-hosted/Linux/X64 레이블도 확인한다. UI에서 Online/Idle을 확인한다. production secret, Docker socket, 운영망 접근을 시험 runner에 제공하지 않는다.

  3. 서비스로 전환한다 — OS별 승인

    대화형 run 프로세스를 먼저 종료한다. 아래 Linux systemd 서비스 설치만 승인된 관리자 권한으로 실행한다. macOS는 공식 launchd 절차, Windows는 config의 서비스 설치 선택과 해당 서비스 계정을 따른다. 전체 workflow를 sudo/root로 실행하지 않는다.

승인 후 변경 · 등록을 마친 Linux systemd runner 설치 디렉터리 · bash
sudo ./svc.sh install runneruser
sudo ./svc.sh start
판정: runneruser는 준비한 비특권 계정으로 바꾼다. 서비스가 시작되고 UI Online/Idle이어야 한다.
조회 · 승인된 Linux runner 설치 디렉터리 · bash
sudo ./svc.sh status
판정: 상태만 조회한다. 프로세스 실행과 GHES 연결 성공을 별도로 확인한다.
ephemeral은 자동 확장 제품명이 아니다

3.21 runner 문서는 --ephemeral 등록을 지원한다. 실제 번들 runner의 옵션·버전 지원을 먼저 확인하고, 1 job 후 등록 해제와 VM/디스크 정리·외부 진단 로그 보존까지 별도 구현한다. Azure VMSS에 runner를 올리는 것만으로 자동 확장·보안 격리가 완성되지 않는다. pilot은 먼저 한 대로 검증한다.

9.2 읽기 조회와 ref 검증

이미 github.example.com에 인증된 gh를 사용한다. 조직 runner 목록의 classic PAT 기준 요구 scope는 admin:org이며 호출자는 조직 관리 권한이 있어야 한다. 여기서는 조회만 하지만 자격 증명 자체가 읽기 전용이라는 뜻은 아니다. 403은 runner 0대가 아니며 권한 담당자에게 전달한다. 토큰을 명령에 넣지 않는다.

조회 · 승인된 관리자 PC · bash
gh api --hostname github.example.com --paginate orgs/testorg/actions/runners --jq ".runners[] | {name,status,busy,labels:[.labels[].name]}"
gh api --hostname github.example.com repos/actions/checkout/git/ref/tags/v4 --jq .object.sha
gh api --hostname github.example.com repos/actions/upload-artifact/git/ref/tags/v3-node20 --jq .object.sha
gh api --hostname github.example.com repos/actions/download-artifact/git/ref/tags/v3-node20 --jq .object.sha
판정: 로컬 bundled/동기화 저장소 기준 ref 확인이다. 404이면 action 공급 경로·권한·tag/branch 유형을 조사한다. 원격 자동 접근 경로는 별도로 확인한다. 운영 적용 시 승인된 commit SHA 고정을 검토한다.

9.3 최소 workflow로 실행과 artifact 왕복을 증명한다

GHES artifact 버전

upload/download-artifact v4 이상은 현재 GHES에서 지원되지 않는다. 아래 v3-node20 두 ref의 action.yml에서 Node 20을 확인했다. upload-artifact의 현재 upstream 안내는 v3.2.2-node20도 제시하므로, 설치 시 최신 GHES 호환 보안 수정·승인 SHA를 확인한다. GitHub.com의 v3 폐기 공지만 보고 GHES를 v4로 교체하지 않는다.

승인된 private testorg/ghes-smoke 저장소 기본 branch에 .github/workflows/ghes-smoke.yml로 저장한다. 파일 생성·commit·push 또는 Contents API PUT은 모두 변경이다. 샘플은 Linux bash 전용이며 synthetic payload만 사용한다. 세션·운영 파일을 artifact로 올리지 않는다.

승인 후 변경 · 승인된 테스트 저장소 · yaml
name: GHES smoke
on:
  workflow_dispatch:
permissions:
  contents: read
jobs:
  smoke:
    runs-on: [self-hosted, linux, x64, ghes-pilot]
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false
      - name: Prepare synthetic payload
        id: payload
        shell: bash
        run: |
          set -euo pipefail
          work="$RUNNER_TEMP/ghes-smoke-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
          mkdir -m 700 "$work"
          printf 'synthetic-ghes-smoke\n' > "$work/payload.txt"
          printf 'work=%s\n' "$work" >> "$GITHUB_OUTPUT"
      - uses: actions/upload-artifact@v3-node20
        with:
          name: smoke-${{ github.run_id }}-${{ github.run_attempt }}
          path: ${{ steps.payload.outputs.work }}/payload.txt
          if-no-files-found: error
          retention-days: 1
      - uses: actions/download-artifact@v3-node20
        with:
          name: smoke-${{ github.run_id }}-${{ github.run_attempt }}
          path: ${{ steps.payload.outputs.work }}/download
      - name: Compare
        shell: bash
        env:
          SMOKE_DIR: ${{ steps.payload.outputs.work }}
        run: cmp "$SMOKE_DIR/payload.txt" "$SMOKE_DIR/download/payload.txt"
      - name: Clean only this run
        if: ${{ always() && steps.payload.outputs.work != '' }}
        shell: bash
        env:
          SMOKE_DIR: ${{ steps.payload.outputs.work }}
        run: |
          rm -f -- "$SMOKE_DIR/payload.txt" "$SMOKE_DIR/download/payload.txt"
          if [ -d "$SMOKE_DIR/download" ]; then rmdir -- "$SMOKE_DIR/download"; fi
          rmdir -- "$SMOKE_DIR"
판정: checkout → synthetic 파일 생성 → upload → download → cmp 성공. job별 RUNNER_TEMP/run ID/attempt 디렉터리만 사용한다. 중간 장애로 남은 파일은 소유 runner의 운영 절차로 정리한다.
승인 후 변경 · 승인된 관리자 PC · bash
gh workflow run ghes-smoke.yml --repo github.example.com/testorg/ghes-smoke --ref main
판정: workflow_dispatch 실행은 저장소 쓰기 권한·사용량·외부 저장소 쓰기를 수반한다. main은 실제 기본 branch로 바꾼다.
조회 · 승인된 관리자 PC · bash
gh run list --repo github.example.com/testorg/ghes-smoke --workflow ghes-smoke.yml --limit 5 --json databaseId,status,conclusion,url
gh run view "$RUN_ID" --repo github.example.com/testorg/ghes-smoke --json status,conclusion,jobs,url
판정: RUN_ID는 바로 위 조회에서 선택한다. UI에서도 각 단계, artifact 이름·크기·다운로드를 확인한다. 로그 전체 복사는 피한다.
증상/시험판정과 다음 작업
QueuedOnline/Idle → 정확한 레이블 전체 일치 → runner group repository allowlist → Actions 정책 순으로 확인한다. 대기를 단순 VM 증설로 해결하지 않는다.
action ref 없음 / Node runtime 오류로컬 bundle·동기화 경로와 SHA, runner 버전·OS 라이브러리를 확인한다. GHES appliance에 Node를 설치하지 않는다.
upload/download 실패외부 저장소 인증과 GHES/runner DNS·TLS·proxy를 각각 확인한다. Phase 8의 UTC 시각/403 분기로 돌아간다.
허용/차단 검증관리자가 아닌 pilot 계정으로 승인된 allowlist 저장소 실행 성공을 확인한다. 별도 승인한 deny 테스트 저장소에는 같은 그룹을 사용할 수 없어야 한다. 예상 차단을 기록하고 대기 job은 승인 후 취소한다.
확대/복구실제 pilot 사용자의 artifact 접근도 검증한다. 실패하면 신규 배포만 멈추고 그룹 allowlist를 이전 승인 상태로 복구한다. 운영 runner 일괄 삭제는 하지 않는다.

공식 근거: Runner 등록·token · OS별 서비스 · 통신·ephemeral · 조직 runner API · Actions 공급 · Upload GHES 지원 · Upload Node20 ref · Download Node20 ref

진행 기준 / 완료 증거: 서비스 재시작 후에도 Online → 비관리자 pilot의 실행·artifact 왕복·cmp 성공 → 승인/비승인 저장소 경계 확인 → 보존·정리·업데이트 책임자 지정. 단순 등록 성공으로 종료하지 않는다.

Phase 10Packages 저장소와 private 배포

상세 참조 장 · STEP 11의 실행 순서·화면으로 돌아가기 →

담당: GHES·Storage·패키지 운영·pilot 개발자선행: 별도 Blob·TLS·시험 namespace·preview 승인산출물: ecosystem 설정·digest·권한 검증·복구 계획

10.1 Actions와 별개로 저장소·생태계를 설계한다

3.21 기준 / 신규 3.22 재확인

두 버전의 Azure Packages 공식 절차는 사전 생성한 container와 account connection string이다. SAS token/SAS URL은 연결 문자열로 지원되지 않으며, Actions의 OIDC 지원을 Packages에 그대로 적용하면 안 된다. Shared Key가 금지된 환경이면 정책 예외 또는 다른 공식 지원 구성을 승인받기 전 진행하지 않는다.

항목·UI입력/선택완료 조건
외부 저장소Actions와 별도 Packages container/bucket 권장. 예: ghes-packages-test. 가능한 별도 account·운영 scope로 분리.container는 Azure에서 먼저 private으로 생성한다. 생성은 변경이다. account key는 container 전용 RBAC 토큰이 아니므로 같은 account의 범위 확대 위험을 평가한다.
네트워크·정책GHES와 실제 package client/runner에서 Blob 접근이 필요한 경로를 검토.IP 제한은 GHES만이 아니라 실제 사용자 접근 경로도 고려한다. GitHub가 공개 bucket을 자동으로 비공개로 만들거나 객체 ACL을 보완하지 않는다.
Site admin → Management Console → PackagesEnable GitHub Packages → Packages Storage = Azure Blob Storage → container name / connection string.비밀 관리자가 UI에만 문자열 입력. 저장 전 계정·container 오타와 정책 확인. Save settings는 서비스 재시작 가능한 변경이다.
Packages → Ecosystem TogglesContainer registry = Enabled, 미사용 생태계 = Disabled. 기존 배포 중단에는 Read-Only 검토.Container registry 항목에는 subdomain isolation이 필요하다. 지원 생태계: Container registry, Docker, RubyGems, npm, Maven/Gradle, NuGet.
Registry 선택이 pilot은 Container registry. legacy Docker registry와 다른 서비스/권한 모델이다.3.21 Container registry는 public preview다. production 허용 여부 승인 필요. legacy Docker를 쓰면 해당 버전 문서를 따르고 주소를 혼용하지 않는다.
용량·운영Container registry는 최소 10% 추가 CPU 계획. root/data·DB·외부 Blob 각각 모니터링.Packages는 Enterprise 제공 기능이어도 Azure 저장·요청·전송·백업 및 VM 비용은 별도다. 무료 인프라라는 뜻이 아니다. GHES clustering에서는 Packages 미지원도 확인한다.

10.2 DNS·TLS·포트를 검증한다

서비스subdomain isolation 사용 시 URL필요 조건
Container registryhttps://containers.github.example.com사용자/runner → TCP 443, DNS와 신뢰 TLS. docker login에는 scheme 없이 host만 사용한다. ghcr.io는 이 GHES의 registry가 아니다.
legacy Docker / npmhttps://docker.github.example.com / https://npm.github.example.com서로 다른 endpoint. npm upstream 사용 시 GHES → registry.npmjs.com TCP 443 경로를 별도로 승인한다.
Maven·Gradle / NuGet / RubyGemshttps://maven.github.example.com / https://nuget.github.example.com / https://rubygems.github.example.com인증서 SAN은 github.example.com 및 필요한 *.github.example.com을 포괄해야 한다. 비활성 생태계까지 임의 공개하지 않는다.
Management Console승인된 관리 경로의 TCP 8443사용자 package 트래픽과 별도 관리 접근이다. registry를 위해 8443을 사용자 전체에게 열지 않는다.
조회 · 승인된 package client 또는 runner · bash
curl --silent --show-error --connect-timeout 10 --max-time 20 --output /dev/null --write-out "HTTP %{http_code}\n" https://containers.github.example.com/v2/
판정: 무인증 401 challenge는 registry 도달성 증거이며 push 권한 증명이 아니다. TLS 오류나 404는 endpoint/기능 설정부터 확인한다. -k를 사용하지 않는다.

10.3 인증 → 작은 private image push/pull

일반 GHES 사용자명 USER를 실제 pilot 로그인으로 바꾼다. SCIM 식별자나 임의의 '%' 접미사를 만들지 않는다. 개인 인증은 해당 GHES에서 발급한 PAT classic의 read:packages / write:packages와 실제 package·연결 저장소 권한이 필요하다. fine-grained PAT로 대체된다고 가정하지 않는다. 삭제 scope는 필요한 관리자에게만 부여한다. repo scope는 registry·private repository 요구를 확인해 최소화하며 무조건 선택하지 않는다.

아래는 승인 후 변경하는 선택적 synthetic 시험이다. bash에서 실행하고 Docker·전용 credential helper가 준비되어 있어야 한다. 토큰은 무표시 입력으로 받으며 credential helper 없이는 Docker 설정에 남을 수 있다. 승인한 private testorg namespace만 사용하고 public registry에 push하지 않는다. 외부 base image 없이 FROM scratch로 만든 데이터 전용 image이며 실행용 컨테이너가 아니다.

승인 후 변경 · 승인된 Linux Docker client의 전용 작업 디렉터리 · bash
(
set -euo pipefail
set +x
work="./ghes-package-smoke-$(date -u +%Y%m%dT%H%M%SZ)-$$"
mkdir -m 700 "$work"
cleanup_auth() {
  original_status=$?
  unset CR_PAT
  if ! docker logout containers.github.example.com; then
    printf 'Credential cleanup failed; follow the approved cleanup procedure.\n' >&2
    test "$original_status" -ne 0 || original_status=1
  fi
  exit "$original_status"
}
trap cleanup_auth EXIT
read -r -s -p 'GHES classic PAT: ' CR_PAT
printf '\n'
test -n "$CR_PAT"
printf '%s' "$CR_PAT" | docker login containers.github.example.com -u USER --password-stdin
unset CR_PAT
printf 'synthetic-ghes-package\n' > "$work/payload.txt"
printf '%s\n' 'FROM scratch' 'COPY payload.txt /payload.txt' \
  'LABEL org.opencontainers.image.source="https://github.example.com/testorg/ghes-smoke"' > "$work/Dockerfile"
image="containers.github.example.com/testorg/ghes-smoke:smoke-$(date -u +%Y%m%d%H%M%S)-$$"
docker build --tag "$image" "$work"
docker push "$image"
docker image inspect "$image" --format '{{json .RepoDigests}}'
printf 'Test image: %s\n' "$image"
rm -- "$work/payload.txt" "$work/Dockerfile"
rmdir -- "$work"
)
판정: Login Succeeded·push digest를 기록한다. 원격 package는 자동 삭제하지 않는다. UI에서 연결 저장소/visibility를 확인하고 보존 만료·승인된 테스트 버전 삭제를 별도로 처리한다. 실패 시 작업 디렉터리와 로컬 image 잔여물을 지정 경로/태그에 한해 정리한다.

다운로드 증명은 캐시 없는 별도 승인 Docker daemon에서 수행한다. 같은 daemon의 pull은 로컬 레이어를 재사용하여 Blob 다운로드 장애를 놓칠 수 있다. 아래 PACKAGE_DIGEST에는 위 push가 반환한 전체 sha256 digest를 넣고, USER에는 read:packages와 실제 package 읽기 권한이 있는 일반 pilot을 사용한다. 별도 PC여도 동일 원격 Docker daemon을 사용하면 독립 검증이 아니다.

승인 후 변경 · 해당 image 레이어가 없는 승인된 별도 Docker daemon/client · bash
(
set -euo pipefail
set +x
: "${PACKAGE_DIGEST:?Set the approved push digest before this test}"
cleanup_auth() {
  original_status=$?
  unset CR_PAT
  if ! docker logout containers.github.example.com; then
    printf 'Credential cleanup failed; follow the approved cleanup procedure.\n' >&2
    test "$original_status" -ne 0 || original_status=1
  fi
  exit "$original_status"
}
trap cleanup_auth EXIT
read -r -s -p 'Pilot read-only classic PAT: ' CR_PAT
printf '\n'
test -n "$CR_PAT"
printf '%s' "$CR_PAT" | docker login containers.github.example.com -u USER --password-stdin
unset CR_PAT
image="containers.github.example.com/testorg/ghes-smoke@$PACKAGE_DIGEST"
docker pull "$image"
docker image inspect "$image" --format '{{json .RepoDigests}}'
)
판정: 실제 레이어 다운로드 성공과 push/pull digest 일치를 모두 확인한다. registry는 읽지만 로컬 credential/image 캐시를 변경하며 저장소 요청·전송 비용이 발생할 수 있다.

10.4 Actions의 GITHUB_TOKEN 경로

workflow 저장소에 연결되어 있고 해당 저장소에 package 접근이 허용된 경우 아래 인증을 사용한다. workflow 수준의 permissions와 job steps에 각각 병합한다. Docker 준비는 runner에서만 한다. 기존 CLI-push package는 연결/Actions access 권한을 확인해야 하며, packages: write 선언만으로 다른 저장소 package 권한이 생기지 않는다. secrets.GITHUB_TOKEN을 별도 PAT로 생성해 저장하지 않는다.

승인 후 변경 · 승인된 테스트 workflow의 병합용 조각 · yaml
permissions:
  contents: read
  packages: write
# 기존 job의 steps에 병합할 단계
steps:
  - name: Authenticate to this GHES registry
    shell: bash
    env:
      PACKAGE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      PACKAGE_USER: ${{ github.actor }}
    run: |
      set +x
      printf '%s' "$PACKAGE_TOKEN" | docker login containers.github.example.com \
        -u "$PACKAGE_USER" --password-stdin
  # 승인된 synthetic image build/push 단계를 이 사이에 추가
  - name: Logout
    if: ${{ always() }}
    run: docker logout containers.github.example.com
판정: 독립 실행 가능한 전체 workflow가 아니다. 실제 publish까지 승인한 경우에만 packages: write를 부여한다. OS credential store 접근도 runner 신뢰 경계에 포함한다.

10.5 장애·백업·완료 판정

확인 항목조치/증거
401 / deniedGHES host·classic PAT scope·사용자 package 권한·저장소 연결·Actions access를 확인한다. SCIM 계정 생성 성공이 package 권한을 보장하지 않는다.
403 / storage 오류Packages connection string·Shared Key 정책·container 존재·firewall을 먼저 본다. Actions OIDC의 SP 역할을 추가하는 방식으로 해결하지 않는다.
push 차단 / toggle 없음Ecosystem Read-Only 상태·subdomain isolation·preview 승인 여부를 확인한다. 기존 private package를 public으로 바꾸어 우회하지 않는다.
백업·보존GHES 설정·DB/메타데이터 백업과 외부 Blob 객체 보호를 분리해 설계한다. GHES 백업 완료가 모든 Blob 백업 완료를 뜻하지 않는다. 객체 lifecycle 자동 삭제가 GHES 참조를 깨지 않도록 retention·soft delete/versioning 호환성을 검토하고 함께 복원 시험한다.
신규 3.22 차이Azure Packages 인증 절차는 동일하게 connection string이다. 3.22 신규 설치는 Backup Utilities 제거 계획을 반영해 내장 Backup Service 문서를 확인한다. DB와 Blob의 일관된 복구 시점·RPO/RTO는 별도 인수 항목이다.
최종 인수비관리자 허용 pilot의 캐시 없는 private package 레이어 다운로드와 별도 미허용 pilot의 거부를 승인된 자원에서 확인한다. digest, 테스트 버전, 접근 결과, 정리 일정만 보관하고 PAT는 회수/회전한다.

공식 근거: 3.21 Azure Packages · 3.22 Azure Packages · 자원·생태계 · Ecosystem toggles · Container registry·인증 · DNS·TLS host map · 백업 서비스 · Backup Utilities 전환

공식 근거: Docker pull·레이어 캐시

진행 기준 / 완료 증거: 설정 적용 성공, synthetic push와 캐시 없는 pull의 digest 일치·실제 레이어 다운로드, 비관리자 allow/deny 확인, secret 정리, 외부 객체 포함 복구 책임자·보존 정책 승인. registry login만 성공한 상태는 미완료다.

Phase 11Copilot 계정·데이터·지원 경계

상세 참조 장 · STEP 11의 실행 순서·화면으로 돌아가기 →

담당: Cloud owner·구매·보안·GHES 관리자·pilot 개발자선행: 계약 경로·데이터 반출·클라이언트 승인산출물: 좌석/정책표·비관리자 pilot·지원 범위·회수 계획

3.21의 경계: GHES 저장소와 Copilot 서비스는 다르다

GHES는 GitHub Enterprise Cloud/EMU가 아니다. 3.21 appliance에 Copilot 모델·Cloud agent 서버를 설치하는 절차가 아니다. 일반적인 서비스 이용은 IDE/CLI의 Copilot 라이선스가 있는 github.com 또는 해당 GHE.com 계정 인증과 GHES의 Git/API 인증을 분리한다. 코드 저장소가 GHES에 있어도 선택된 prompt·코드 문맥이 모델 서비스로 전송될 수 있다.

신규 3.22의 중요한 예외 — Technical preview

3.22.0(2026-09-08) 공식 릴리스에는 GHES 관리자가 모델 공급자를 구성하고 사용자가 GHES 자격 증명으로 Copilot CLI를 사용하는 disconnected/air-gapped 구성이 추가되었다. 이를 3.21에 소급 적용하지 않는다. 이는 공식 CLI 연동 preview이며 GitHub-hosted 모델이나 Copilot cloud agent를 GHES에 설치하는 기능이 아니다. 외부 모델 endpoint를 선택하면 그 공급자로의 통신·문맥 전송은 여전히 필요하며, 완전 폐쇄망은 승인된 내부 호환 모델 endpoint와 도구 경계를 별도로 구성해야 한다. 운영 도입은 별도 검토한다.

11.1 구매·계정 경로를 선택한다

경로판정담당자 확인
기존 Cloud enterprise의 Copilot라이선스가 할당된 Cloud 사용자로 IDE/CLI 인증. GHES 사용자와 별도 계정/정책 영역.GHES Git 인증과 Copilot 인증을 각각 기록한다. 같은 Entra IdP라고 사용자·토큰·tenant가 같다고 가정하지 않는다.
Copilot Business 전용 Cloud enterprise일반 Cloud enterprise에 사용자를 직접 추가해 organization 비소속(unaffiliated)으로 관리하면 추가 GHEC 좌석을 소비하지 않는 구성이 가능하다.Copilot Business는 과금된다. GHES 라이선스가 공짜가 되는 구조가 아니며 기존 조직 삭제로 비용을 회피하는 절차를 만들지 않는다.
PAYG Cloud + GHES license fileGHES 파일 좌석은 생성 시점의 consumed Cloud enterprise licenses 기준. 공식 문서의 Cloud organization 사용자 할당 등 조건을 충족해야 한다.Billing & Licensing → Licensing의 소비 좌석을 확인한다. Copilot 좌석이나 People의 Total consumed로 대체하지 않는다. Server-only 사용자 청구/중복 제거와 GitHub Connect 요건도 확인한다.
Volume / subscription GHES 계약구매 사용자 수와 계약 기간에 맞춘 GHES 권한. Cloud-only/Server-only/양쪽 사용 조건은 계약 확인.Copilot-only enterprise 설명을 PAYG GHES 라이선스 우회 규칙으로 적용하지 않는다.
선택: EMUCloud 관리형 계정 운영이 필요한 경우에만 별도 Cloud/IdP 프로젝트로 진행.GHES SCIM 또는 GHES 조직을 Cloud EMU로 간주하지 않는다. 이 단계에서 Cloud 조직·enterprise를 삭제하거나 마이그레이션하지 않는다.

11.2 Cloud 경로의 pilot UI와 실행 순서

  1. 책임자·승인표를 만든다

    구매 담당은 상품/좌석/예산, Cloud enterprise owner는 AI controls, 보안 담당은 모델·클라이언트·MCP·데이터 반출, GHES 관리자는 코드 접근을 담당한다. 허용 IDE/CLI 버전, 모델, repository, tool별 read/write 범위와 폐기 일정을 작성한다.

  2. 좌석과 정책을 적용한다 — 변경

    Cloud enterprise의 Copilot access 관리 화면에서 pilot을 할당한다. AI controls에서 모델·클라이언트·agent·MCP 관련 정책을 검토한다. 직접 할당 사용자는 Policies for enterprise-assigned users도 확인한다. GHES Management Console의 Actions/Packages 화면에서 설정하는 것이 아니다.

  3. 개발자 로그인과 출구를 분리 확인한다

    IDE의 Copilot 로그인에서 라이선스 계정을 선택한다. CLI 일반 Cloud 로그인도 github.com 또는 GHE.com 경로를 사용한다. github.example.com을 Cloud Copilot 로그인 host로 무조건 넣지 않는다. 인증·모델 호출의 최신 공식 allowlist와 proxy CA를 승인하고 TLS 검증을 유지한다. GHES clone/push 인증은 별도로 준비한다.

  4. synthetic 문맥으로 시험한다

    승인된 private testorg 저장소의 무해한 예제 함수만 열고 ‘이 함수의 단위 테스트 초안을 제안하라’고 요청한다. 첫 시험은 제안 검토로 제한하고 파일/명령/MCP 쓰기 실행은 금지한다. 모델 응답·라이선스 인식·정책 차단·GHES read 접근 결과를 각각 기록한다.

  5. 비관리자와 차단 조건을 확인한다

    pilot 일반 사용자로 재현하고, 승인된 비허용 모델/도구 또는 테스트 계정으로 차단을 확인한다. 광범위 토큰을 발급해 실패를 숨기지 않는다. 응답 원문보다 성공/거부, client·model 버전, 시각, 정책 식별자를 보관한다.

11.3 CLI/SDK BYOK·3.22 preview를 구분한다

선택준비·입력넘지 말아야 할 경계
3.21 + 로컬/외부 CLI·SDK BYOK공식 BYOK 문서에 따라 승인한 외부 또는 로컬 모델과 secret store를 선택. GHES 접근 도구에 별도 자격 증명·DNS·TLS·최소 권한 제공.사용자 정의 자동화이지 GHES 네이티브 cloud agent가 아니다. 로컬 BYOK는 GitHub 인증 없이 가능한 경로가 있으나 GHES API 작업의 인증까지 없어지지 않는다.
Enterprise BYOKCloud 측 사용자 정의 모델 정책·라이선스·인터넷 조건을 별도 검토.로컬 BYOK와 동일한 과금·인증·오프라인 모델이라고 가정하지 않는다. 외부 모델이면 데이터는 외부 공급자로 전송된다.
3.22 preview 관리자승인된 SSH 절차로 app.copilot-proxy의 enabled, endpoint-url, provider-type, provider-model-id 및 공급자 비밀을 구성. 공식 문서의 옵션/지원 공급자 확인.비밀 값의 인라인 명령은 여기서 제공하지 않는다. 관리자 비밀 주입 절차와 ghe-config-apply 작업창 승인이 선행한다. appliance에 LLM을 설치하는 것으로 설명하지 않는다.
3.22 preview 사용자COPILOT_PROVIDER_GHES_HOST=github.example.com, COPILOT_PROVIDER_GHES_TOKEN=승인된 비밀 주입, COPILOT_OFFLINE=true. gh의 GHES 인증 별도 확인.호스트값 외에 토큰 실값은 표·로그·명령 history에 넣지 않는다. Cloud 연계 기능은 동일하게 동작한다고 보장하지 않는다. 지원 범위는 해당 preview 문서를 기준으로 한다.

3.22 preview가 승인·구성된 경우에만 아래 로컬 설정을 사용한다. 사전에 해당 GHES에 인증된 gh가 있어야 한다. 토큰은 stdout에 인쇄하지 않고 동적으로 받는다. API key 설정이나 preview 활성화를 이 명령이 대신하지 않는다.

로컬 세션·파일 · 3.22 preview 승인 pilot의 개발 PC · bash
set +x
COPILOT_PROVIDER_GHES_HOST=github.example.com
if COPILOT_PROVIDER_GHES_TOKEN="$(gh auth token --hostname "$COPILOT_PROVIDER_GHES_HOST")" &&
   test -n "$COPILOT_PROVIDER_GHES_TOKEN"; then
  export COPILOT_PROVIDER_GHES_HOST COPILOT_PROVIDER_GHES_TOKEN
  export COPILOT_OFFLINE=true
  printf 'Client environment prepared. Start only the approved CLI session.\n'
else
  unset COPILOT_PROVIDER_GHES_TOKEN COPILOT_PROVIDER_GHES_HOST COPILOT_OFFLINE
  printf 'STOP: no approved GHES token was retrieved.\n' >&2
fi
판정: 셸 환경만 구성한다. 토큰 조회 실패 시 성공으로 진행하지 않는다. 시작 전 client/provider 버전과 secret 취급을 확인한다. 종료 후 이 세 변수를 unset한다. 환경변수는 민감한 프로세스 데이터이므로 전용 세션에서만 사용하고 Cloud 모드와 섞지 않는다.

11.4 운영 정책·장애 분류와 인수

주제운영 기준
데이터 문맥·content exclusion현재 공식 문서는 CLI content exclusion 지원을 안내하지만 클라이언트·모드별 차이와 간접 semantic 정보·symlink/remote filesystem 한계가 있다. ‘모든 도구/모드에서 완전 차단’으로 보장하지 않는다. GHES 저장소에 실제 적용되는 정책 범위도 pilot에서 확인한다.
MCP·SDK·외부 도구서버별 승인·도구 allowlist·토큰 scope·응답 데이터·명령/파일 쓰기 승인을 분리한다. content exclusion만으로 모든 MCP 응답과 사용자 정의 SDK 전달 데이터가 보호된다고 가정하지 않는다.
계정/좌석 오류Copilot에 로그인한 Cloud 계정과 좌석·조직 정책부터 확인한다. GHES Git 로그인 성공을 Copilot 라이선스 증거로 삼지 않는다. 3.22 preview는 별도 provider/GHES token 경로를 점검한다.
네트워크/모델 오류Cloud 또는 BYOK 공급자 endpoint·DNS·TLS·proxy·모델 허용·비용 제한을 구분한다. GHES REST 403과 모델 공급자 인증 실패는 서로 다른 원인이다.
Cloud agent 요청3.21 GHES 저장소를 공식 Copilot cloud agent의 네이티브 대상으로 안내하지 않는다. 3.22 CLI preview도 cloud agent 설치가 아니다. 자동 PR 생성이 필요하면 별도 커스텀 통합으로 승인·감사·최소 권한을 설계한다.
중단/회수pilot 좌석 회수, 승인 도구 중지, 토큰 폐기, 로컬 인증/환경 정리를 각 소유자가 수행한다. GHES 저장소 삭제 또는 Cloud 조직 삭제는 중단 절차가 아니다.

공식 근거: Copilot 요금제·GHES 경계 · Business 전용 enterprise · Cloud/Server 청구 구분 · Cloud 정책·AI controls · 좌석 할당 · Cloud CLI 인증 · 네트워크 allowlist · 선택 참고: EMU · BYOK · SDK BYOK · Content exclusion · 문맥과 책임 있는 사용 · Cloud agent · 3.22 릴리스 · 3.22 CLI technical preview

최종 검토일: 2026-09-19. Cloud/CLI 문서는 지속 변경된다. 위 날짜는 공개 문서 검토일이지 실제 고객 환경 인증일·지원 보증일이 아니다. rollout 전 해당 버전·계약·정책을 다시 확인한다.

진행 기준 / 완료 증거: 3.21 Cloud 경로 또는 별도 승인한 3.22 preview/BYOK 경로 명시, GHES와 AI 인증 분리, synthetic 응답 및 정책 차단 확인, 데이터 처리·MCP·비용·회수 책임자 승인. GHES 네이티브 cloud agent 설치로 인수하지 않는다.

Phase 12모니터링·감사·운영 점검

상세 참조 장 · STEP 12의 실행 순서·화면으로 돌아가기 →

담당: 운영·보안·라이선스 담당선행: 입력표·관리 접근·수집/반출 승인산출물: 기준선·점검표·알림 시험·제한된 증거

운영 입력과 권한부터 확인

공개 공식 문서를 기준으로 모니터링·로그 조사·운영 검증 절차를 설명합니다. 기본 절차는 GHES 3.21입니다. Phase 0의 입력표에 승인된 FQDN·환경 구분·실제 패치·토폴로지·관리 SSH 키·관리 콘솔 접근·증거 보관 폴더·담당자·알림 수신자·변경 번호를 기록합니다. 아래 HOSTNAME 등은 승인된 실제 값으로 바꾸는 자리표시자입니다. GHES site admin, Enterprise owner, Management Console 관리자, Cloud billing 담당 권한을 서로 같은 것으로 취급하지 않습니다.

12.1 매일 보는 화면과 정상·실패 분기

  1. 접속·시간·대상 확인

    Site admin → Management Console → Monitor. HA/cluster는 노드 선택을 확인하고 같은 시간대의 정상 기준선과 비교합니다. 장애 시작·끝은 UTC로 기록합니다.

  2. 운영 상태에서 원인으로 이동

    Operational Health에서 이상 구간을 찾고 System & Application Insights의 CPU·Memory·Storage·Application Health·Background jobs·Actions를 비교합니다. CPU만 보지 말고 I/O 지연, 디스크 포화, 요청 큐, 백그라운드 적체와 배포 시점을 함께 봅니다.

  3. 이상 시 변경보다 증거 확보

    노드·UTC 구간·지표·영향 기능을 먼저 남깁니다. 인증 오류, 스토리지 지연, Runner 부족을 구분하고 담당자에게 전달합니다. 서비스 재시작·확장·에이전트 설치를 일상 조회 명령에 섞지 않습니다.

점검정상 판정실패 시 조치 / 증거
CPU·RAM업무량 대비 건강한 기준선; Linux 캐시를 누수로 단정하지 않음지속 상승과 응답 지연 동반 여부, VM 예약·경합·실행 중 백업을 확인
디스크·I/Oroot와 /data/user를 따로 추적; 여유·증가율·지연 측정공식 저장소 경고 60% / 위험 75%를 출발점으로 운영 임계값 승인; 삭제 대신 용량 계획
요청·작업 큐큐가 해소되고 p90 응답 시간·오류율 안정Queued requests의 No data는 대기 없음일 수 있음; 수집 장애와 구별
Actions서비스 요청·MSSQL 지표와 실제 작업 성공 모두 확인조직/저장소 Actions → Runners 및 대기 작업의 labels·runner group·외부 저장소를 별도 점검
알림·복구승인된 시험 알림이 담당자에게 도착하고 최근 복구 시험 증거 존재그래프·메일 설정 화면만으로 알림 설정 또는 복구 완료를 주장하지 않음
400 GB root가 200 GB로 보이는 이유

공식 구조 예시는 root 볼륨 400 GB 중 root filesystem 200 GB, 나머지 절반은 업그레이드·롤백용입니다. 3.14 이후 신규 설치에는 작은 BIOS/UEFI 파티션도 있으므로 실제 바이트 수는 따로 확인합니다. 사용자 데이터 볼륨 /data/user는 별개입니다. 예약 영역을 여유 데이터 디스크로 합산하거나 root 표시만 보고 디스크 누락으로 판단하지 않습니다.

조회 · 관리자 PC에서 SSH 연결 후 GHES 관리 셸 · bash
ssh -p 122 admin@HOSTNAME
ghe-version
ghe-service-list
ghe-system-info
ghe-license info
ghe-license check
df -h / /data/user
판정: 예상 버전·서비스·라이선스 유효성 확인. 출력에는 내부 정보가 있으므로 원본은 제한 보관. 연결 실패 시 DNS·TCP 122·키 권한부터 확인.

12.2 제한된 로그 조사와 지원 자료

경로 / 선택자용도조회 원칙
/var/log/github/exceptions.log애플리케이션 예외장애 UTC 구간과 연관된 최근 행부터
/var/log/github/audit.log사용자·저장소·시스템 이벤트원본에는 신원·저장소 정보가 포함될 수 있음
/var/log/enterprise-manage/unicorn.log관리 콘솔 UI/API HTTP 요청SMTP 자격 증명·요청 본문을 공유하지 않음
/data/user/common/ghe-config.log최근 설정 적용·업그레이드 진행출력 중단은 실패일 수 있음; 완료로 오인 금지
journalctl -t github-unicorn웹/API 요청 및 인증 관련 기록UTC 시작·끝·최대 200행으로 제한

조회할 UTC 시작·끝을 먼저 지정: 승인된 관리 셸에서 START_UTC와 END_UTC를 실제 실패 구간의 YYYY-MM-DD HH:MM:SS UTC 값으로 설정합니다. 기본값은 없으며 미설정·빈 값이면 조회하지 않습니다. UTC 구간 지정을 참고합니다. ghe-config.log는 최근 설정 적용 조사용이며 SCIM 기본 조회 대상이 아닙니다.

조회 · 승인된 GHES 관리 셸 · bash
(
  : "${START_UTC:?Set START_UTC to the actual start: YYYY-MM-DD HH:MM:SS UTC}"
  : "${END_UTC:?Set END_UTC to the actual end: YYYY-MM-DD HH:MM:SS UTC}"
  tail -n 200 /var/log/github/exceptions.log
  tail -n 200 /data/user/common/ghe-config.log
  journalctl -t github-unicorn --utc --since "$START_UTC" --until "$END_UTC" -n 200 --no-pager
)
판정: 실제 UTC 시작·끝을 사전 설정해야 조회. journalctl 시간·행 제한은 표준 옵션이며 GHES 문서는 tag를 확인해 줌. tail은 시간 필터가 아니므로 각 행의 시간을 확인.
필터링 ≠ 비식별화

선택적으로 grep으로 범위를 줄여도 전체 비밀·개인정보가 제거되지는 않습니다. 원본 로그·지원 번들은 접근 제한 보관하며, 공유본만 별도 검토·비식별화합니다. MIP/DLP 또는 조직 정책상 반출 불가한 실제 데이터는 외부 서비스·채팅에 첨부하지 않습니다. SMTP 비밀번호나 토큰을 로그에 출력하는 진단은 하지 않습니다.

로컬 세션·파일 · 승인된 관리자 PC; 이미 준비된 접근 제한 로컬 폴더 · bash
(
  umask 077
  set -C
  ssh -p 122 admin@HOSTNAME -- 'ghe-support-bundle -p 2days -o' > ./APPROVED-LOCAL-FOLDER/CASE-UTC-UNIQUE-support.tgz
)
판정: 서버 진단 생성·로컬 파일 쓰기 승인이 필요. 종료 코드 0과 비어 있지 않은 정상 압축 파일을 확인. 기존 파일 덮어쓰기는 차단하며 실패 시 부분 파일을 성공 자료로 사용하지 않음.

폴더·파일 이름은 승인된 실제 값으로 치환합니다. 호스트 키 검증을 끄지 않습니다. UI 대안은 Management Console → Support → Download support bundle입니다. geo-replication/cluster는 공식 절차의 ghe-cluster-support-bundle -p 2days -o 적용 여부를 확인합니다. -u·-t 자동 업로드 옵션은 사용하지 않으며 생성 후에도 반출 승인은 별개입니다.

12.2.1 기본 로그는 어디서 보는가

  1. 대상과 권한 고정

    승인된 관리자 PC에서 위 ssh -p 122 admin@HOSTNAME으로 연결합니다. HOSTNAME은 실제 승인된 GHES 호스트로 치환합니다. 예시 https://github.example.com/api/v3/scim/v2는 승인된 실제 호스트로 바꿉니다. GHES용 Entra 앱·테넌트·실제 Tenant URL을 확인하고 Cloud용 앱과 구분합니다.

  2. 최근 일부만 조회

    아래는 기본 애플리케이션 로그의 최근 100행입니다. 파일 전체나 최근 100분이 아닙니다. 행별 시각·시간대·노드와 실제 실패 구간을 대조합니다. 읽기 권한 오류는 기록 부재가 아니며 임의 권한 변경으로 우회하지 않습니다.

조회 · 승인된 GHES 관리 셸 · bash
tail -n 100 /var/log/github/production.log
판정: 최근 애플리케이션 기록 100행까지만 조회. 요청 경로·오류 문맥을 확인하되 HTTP 수신 증거와 별도로 대조.
조회 · 승인된 GHES 관리 셸; 필요한 경우만 짧게 관찰 · bash
tail -n 100 -F /var/log/github/production.log
판정: 최근 100행 다음에 새 기록을 계속 표시. 예: 1~2분 관찰 후 Ctrl+C로 조회기를 종료하며 서비스는 중지되지 않음.

12.2.2 최근 구간과 정확한 UTC 구간

조회 · 승인된 GHES 관리 셸 · bash
journalctl -t github-unicorn --utc --since '20 minutes ago' --no-pager -n 200 -o short-iso
판정: 실행 시점 기준 최근 20분 중 최대 200행. 장애가 더 이전이거나 요청량이 많으면 이 결과만으로 누락 여부를 판단하지 않음.
실제 UTC 시작·끝 입력 필수 — 기본값 없음

실패 이벤트의 날짜·시간대를 확인하고 같은 관리 셸에 START_UTC와 END_UTC를 YYYY-MM-DD HH:MM:SS UTC 형식으로 설정합니다. 시작이 끝보다 앞선 제한된 구간인지 확인합니다. KST(UTC+9)는 9시간을 빼 UTC로 환산합니다(예: 18:30 KST → 09:30 UTC). 자정을 넘으면 날짜도 조정합니다. 변수가 없거나 비어 있으면 아래 subshell만 중단하며 조회하지 않습니다.

조회 · 실제 장애 UTC 구간 확인 후 승인된 GHES 관리 셸 · bash
(
  : "${START_UTC:?Set START_UTC to the actual start: YYYY-MM-DD HH:MM:SS UTC}"
  : "${END_UTC:?Set END_UTC to the actual end: YYYY-MM-DD HH:MM:SS UTC}"
  journalctl -t github-unicorn --utc --since "$START_UTC" --until "$END_UTC" --no-pager -n 200 -o short-iso
)
판정: 구간 내 최대 200행. 200행에 도달하면 창을 더 작게 나누어 확인하고 전체 구간을 다 봤다고 단정하지 않음.

12.2.3 SCIM: HTTP 수신부터 애플리케이션 오류까지

Entra의 사용자별 provisioning event에서 실패 단계·상세 응답을 먼저 확인합니다. 할당 직후 사용자가 없으면 자동 주기의 진행·대기와 Stopped 상태를 구분합니다. 승인된 단일 시험 사용자의 이벤트를 대조하며 전체 재프로비저닝으로 진단을 시작하지 않습니다.

조회 · 승인된 GHES 요청 처리 노드의 관리 셸 · bash
tail -n 1000 /var/log/nginx/github.log | grep -F '/api/v3/scim/v2' | tail -n 50
판정: 최근 HTTP 로그 1000행 중 SCIM 경로가 있는 마지막 50행까지만 표시. 시간 필터가 아니며 무출력은 서버 미호출의 증명이 아님.

journal은 먼저 위의 필터 없는 제한 조회로 시각과 형식을 확인합니다. 필요할 때만 아래 추가 필터를 사용합니다. tag·메시지 형식에 경로가 없거나 최대 행 수 밖이면 검색되지 않습니다.

조회 · 승인된 GHES 관리 셸; 필터 없는 조회 후 선택적으로 사용 · bash
journalctl -t github-unicorn --utc --since '20 minutes ago' --no-pager -n 200 -o short-iso | grep -F '/api/v3/scim/v2'
판정: 최근 20분·최대 200행 안에서만 추가 검색. 결과가 없으면 필터 없는 기록·정확한 실패 창·HTTP 로그를 다시 대조.

메서드·경로·응답을 함께 읽기

원본 응답 / HTTP 상태가능한 의미다음 확인
GET 200조회 성공; 사용자 생성 성공이 아님Users 조회·연결 검사와 실제 생성 POST를 구분
POST 201사용자 생성 요청 성공반환된 대상 ID와 실제 GHES 사용자·감사 이벤트를 대조
PATCH 200 / 204업데이트 요청 성공active·roles 등 실제 변경 속성 확인; 신규 생성으로 집계하지 않음
400응답 상세가 중요; out of seats 등상세 문구가 좌석 부족이면 설치 키 한도·소비 확인. 모든 400을 좌석 부족으로 단정하지 않음
401 / 403인증·인가 또는 경계 proxy/WAF 거부 가능GHES 원본 응답인지 경계 장비 응답인지 확인 후 호스트·토큰·권한 대조
5xx서버 또는 upstream 오류 가능동일 UTC·노드·request ID의 exceptions 및 nginx error를 대조

LB/WAF의 상태와 GHES 원본(origin) 상태를 구분합니다. HTTP 200인 HTML 로그인 응답은 SCIM 성공이 아닙니다. 메서드·경로·UTC·source/target ID·request ID를 기록하고 실제 응답에서 확인된 값만 사용합니다. Entra Change ID는 자동으로 GHES request ID가 되지 않습니다. 일치가 확인되지 않으면 각 ID를 별도 필드로 보관하고 시간·대상·작업을 함께 대조합니다.

12.2.4 신원 이벤트·예외 교차 확인

조회 · 승인된 GHES 관리 셸 · bash
tail -n 1000 /var/log/github/audit.log | grep -E 'external_identity|user\.(create|suspend|unsuspend|rename)' | tail -n 50
판정: 최근 1000행 안의 신원 연결·생성·정지·복원·이름 변경 후보만 표시. 이벤트명·대상 ID·시각을 원문에서 확인.
조회 · 승인된 GHES 관리 셸 · bash
tail -n 100 /var/log/github/exceptions.log
tail -n 100 /var/log/nginx/github.error.log
판정: 각 파일 최근 100행의 예외·upstream 오류를 production.log 및 HTTP 수신 기록과 대조. 단독 오류 문구로 원인을 확정하지 않음.

감사 이벤트는 HTTP 요청 로그의 대체물이 아닙니다. 실패한 생성은 사용자 생성 감사 이벤트를 남기지 않을 수 있습니다. GHEC에 무작위처럼 보이는 계정명이 있다는 사실만으로 새 신원 생성이나 GHES 계정과의 동일성을 확정하지 않습니다. 호스트·Entra 객체·externalId·대상 ID·생성 시각을 비교합니다.

12.2.5 라이선스 UI·설정 적용은 별도 분기

Management Console의 라이선스 업로드·갱신 UI/API 오류를 조사할 때만 콘솔 로그를 추가합니다. 일반 GHES License 화면 오류는 먼저 해당 요청의 production/journal/HTTP 기록을 확인합니다. SCIM 기본 조사에 콘솔·설정 로그를 무조건 섞지 않습니다.

조회 · Management Console 라이선스 UI·갱신 오류를 조사하는 승인된 GHES 관리 셸 · bash
tail -n 100 /var/log/enterprise-manage/unicorn.log
판정: 콘솔 요청 시각·상태를 대조. 자격 증명·요청 본문 등 민감 필드가 있을 수 있으므로 원문 공유 금지.
조회 · 최근 설정 적용·업그레이드와 오류 시점의 관련성을 조사하는 승인된 GHES 관리 셸 · bash
tail -n 100 /data/user/common/ghe-config.log
판정: 설정 적용의 시작·완료·실패를 구분. 최근 적용이 없으면 SCIM 진단의 기본 출발점으로 사용하지 않음.

새 라이선스 키 업로드나 재시작 뒤 정상화가 관측되더라도 이는 변경 후 관측입니다. 키 한도·실패 상세·변경 전후 요청을 비교하지 않고 근본 원인이 입증됐다고 쓰지 않습니다. 라이선스와 Connect의 사용량 동기화는 분리하며 Sync/Enable만으로 설치 키의 좌석 한도가 늘어날 것으로 기대하지 않습니다.

12.2.6 내장 통합 로그 관찰 — 선택 사항

조회 · 승인된 GHES 관리 셸; 특정 로그로 좁히기 어려운 경우만 · bash
ghe-logs-tail
판정: GHES 내장 도구로 관련 로그를 함께 관찰하므로 출력량·민감 정보가 많을 수 있음. 1~2분 등 짧은 관찰 후 Ctrl+C로 종료.

이 통합 관찰과 tail -F는 총 출력 행 수가 제한되지 않습니다. 기본 선택은 위의 제한된 조회이며 Ctrl+C는 조회기만 종료하고 GHES 서비스는 중지하지 않습니다. 파일 전체 복사나 무기한 수집으로 대체하지 않습니다.

12.2.7 무출력·연결 오류·자료 취급 주의 조회표

관측 / 오해안전한 확인 / 중단 기준
grep 무출력 = 서버 호출 없음?아님. 실제 GHES 앱·Tenant URL(Cloud 아님), 요청 처리 노드·LB 경로, UTC/시간대, 보존·회전 파일, 마지막 N행·검색 필터를 확인. 기본 시스템 로그는 24시간마다 회전·회전 로그 7일 보존이며 실제 정책도 확인
Connect의 일반적인 cannot connect / cannot verify 메시지NTP 장애 확정이 아님. DNS·TLS·아웃바운드·proxy와 실제 시간 오차를 각각 확인. NTP/disconnect는 원인 증거를 대신하지 않으며 Disable 후 재연결을 기본 처방으로 삼지 않음. Connect 참조
일시적으로 proxy 없이 넓은 outbound 허용 후 연결운영 최종 구성 완료가 아님. 승인된 최소 목적지·포트와 proxy 경유 재시험, 임시 규칙 회수·담당·기한을 남김. 네트워크 참조
기본 로그에 정보가 부족함debug 활성화·DB 콘솔·tcpdump·추가 패키지 설치·서비스 재시작을 기본 진단에 포함하지 않음. 제한된 증거와 미확인 사항을 정리해 승인된 지원 절차로 이관
읽기 전용이면 공유해도 됨?아님. 신원·이메일·내부 경로·요청 본문·토큰·SAML assertion·쿠키·자격 증명이 포함될 수 있음. 원문은 접근 제한 보관, 공유본은 별도 비식별화·승인. grep은 비식별화 도구가 아님

연결·프로비저닝·라이선스 완료는 실제 환경에서 각각 검증합니다. 증상별 출발점은 부록의 로그·주의사항 빠른 조회, 신원 흐름은 SCIM을 참조합니다.

12.3 감사·알림·수명주기·라이선스 운영

대상화면 / 절차오해 방지·완료 증거
감사 보존Enterprise settings → Settings → Audit log → Audit Data RetentionEnterprise 보존기간은 구성값 기준. Git 이벤트 활성화 전 infinite가 아닌 기간 필요. 조직 감사 화면의 최근 180일 안내를 Git 이벤트 전체의 고정 180일 보존으로 일반화하지 않음
서버 로그시스템 로그 수집·보존 정책과 별도 확인기본 24시간마다 rotation, 회전 로그 7일 보존. 지원 번들의 2일 수집 범위와도 다름
SyslogManagement Console → Settings → Monitoring → Enable log forwarding승인된 수신지·TLS·접근권한·보존·방화벽 확인 후 설정/시험; 일반 설정 예시와 실제 데이터 반출 분리
감사 스트리밍Enterprise settings → Settings → Audit log → Log streaming외부 목적지 사전 승인. 활성화 이후 데이터, at-least-once 전달이므로 중복 처리·수신 지연 시험
SMTP 알림Management Console → Settings → Email; 승인 후 Test email settings / Send test email송신 relay의 승인 포트 사용: 587/STARTTLS 예시와 25를 구별. 회신 수신은 GHES inbound 25·MX 별도 설계
만료·갱신TLS·IdP 서명 인증서·PAT·App 자격 증명·GHES 라이선스 만료 목록각 소유자·대체 담당·갱신 창·사전 알림 일정·시험 수신 증거 기록; 이 문서가 알림을 설정한 것은 아님
조회 · 해당 GHES에 사전 인증·인가된 관리자 PC의 GitHub CLI · bash
gh api --hostname HOSTNAME --method GET /enterprise/settings/license
판정: seats / seats_used / seats_available / expire_at / days_until_expiration 비교. 401·403은 호스트·인증·인가 확인; 문서에 없는 토큰 scope를 추정하거나 확대하지 않음.

UI는 Enterprise settings → Settings → License입니다. ghe-license info와 ghe-license check만 일상 조회에 사용하며 --used는 포함하지 않습니다. Code Security·Secret Protection 또는 기존 Advanced Security 계약은 활성 저장소의 최근 90일 내 push된 커밋의 고유 active committer를 기준으로 검토합니다. 저장소별 수를 단순 합산하거나 사용자별 좌석 체크박스로 수동 배정하는 모델로 설명하지 않습니다. GHEC 청구·Copilot 구독/정책은 별도이며 확인하지 않은 Cloud 화면을 GHES 경로로 만들지 않습니다.

운영 시험승인된 목표 / 관측합격·실패 처리
가용성 SLO업무 시간·성공 요청 비율·측정 창·제외 조건 합의실제 측정치와 목표 비교; 임의 가용성 보장 금지
RPO / RTO13장의 마지막 복구 가능 시점·복구 완료 시간목표 초과 시 주기·용량·복구 절차 수정 후 재시험
퇴사 soft 차단승인된 시험 사용자로 IdP 차단과 GHES 계정 정지·자격 증명 정책 확인웹·Git·API 접근 거부와 조직/자산 보존 확인; IdP 차단만으로 모든 PAT 차단을 가정하지 않음
hard 삭제법무 보존·자산 이관·감사·복구 승인 후 별도 변경운영 삭제 명령 제공 안 함; 시험 성공을 운영 삭제 승인으로 해석 금지

공식 근거: 3.21 Monitor · 임계값 · 스토리지 구조 · 로그·회전 · CLI · 지원 자료 · 감사 보존 · 조직 감사 180일 · 감사 스트리밍 · Syslog · SMTP · 라이선스 API · Security 청구

진행 기준 / 완료 증거: 노드별 정상 기준선, 감사/로그 보존 구분, 알림 수신 및 만료 책임자 확인. 조회 실패와 미설정 알림은 미완료.

Phase 13백업·복구·재해 복구 훈련

상세 참조 장 · STEP 12의 실행 순서·화면으로 돌아가기 →

담당: GHES·스토리지·네트워크 담당선행: 백업 저장소·격리 STAGING·변경 승인산출물: 성공 snapshot·복구 증거·관측 RPO/RTO

13.1 Backup Utilities와 Backup Service: 확인된 사실과 미확인 사항

3.21 Utilities 문서는 Service를 권장하고 Utilities를 “scheduled for removal in … version 3.22”라고 명시합니다. 3.22.0 GA 릴리스 노트(2026-09-08)에서는 Utilities의 실제 제거·deprecated 항목을 확인하지 못했습니다. 제거 예정과 제거 완료는 다릅니다. 3.22 Utilities 문서 URL이 Service 설명으로 이동하는 사실도 실행 파일 제거의 증명은 아닙니다. 따라서 ‘3.22에서 제거 완료’ 또는 ‘3.22에서도 계속 지원’ 어느 쪽도 단정하지 않고 전환·지원 여부를 업그레이드 차단 조건으로 둡니다.

방식실제 구조운영 선택
기존 Backup Utilities / 3.21별도 Linux backup host에 설치, SSH로 GHES에서 수집; backup.config의 GHE_DATA_DIR에 저장운영 중인 원격 호스트의 버전·키·일정·복구 시험을 먼저 기록. appliance에 무작정 설치하지 않음
Backup Service / 3.21·3.22GHES 내장·관리 콘솔 관리; 별도 백업 소프트웨어 호스트 불필요, 전용 볼륨 /data/backup조회한 두 버전 문서는 NFS mount를 피하도록 안내. NFS 서버/경로 입력 UI를 만들어 넣지 않음
독립 보관같은 장애 영역의 연결 디스크 하나는 사이트 DR을 충족하지 못함암호화·접근 분리·별도 사이트 보관·복원 가능한 사본·retention/immutability는 별도 스토리지 정책으로 검증
HAactive/passive 비동기 복제; 손상·삭제도 전파 가능HA ≠ 백업. 수동 승격·DNS/LB 전환·split-brain 방지가 필요

13.2 백업 입력표 → 초기 설정 → 첫 성공

  1. 저장소 승인

    Phase 0의 입력표에 백업 방식·소스 버전·전용 디스크 ID·용량·마운트·복구 대상·UTC 일정·보존 개수·RPO/RTO·담당자를 기록합니다. Service는 primary 데이터 디스크 사용량의 최소 5배, 대소문자 구분 및 hard/symbolic link 지원을 확인합니다. Utilities 문서의 primary 할당량 5배 권고와 혼동하지 않습니다.

  2. Service 저장소 준비 — 파괴 작업 분리

    하이퍼바이저에서 승인된 전용 디스크를 연결하고 아래 조회로 식별합니다. 신규 빈 디스크에 한해서 공식 ghe-storage-init-backup 초기화 절차를 2인 확인 후 수행합니다. 초기화는 해당 장치를 포맷·삭제하므로 복사 가능한 포맷 명령은 제공하지 않습니다. 기존 초기화 디스크는 재포맷하지 말고 공식 재사용 절차로 mount service를 활성화합니다. root·data 디스크와 불명확하면 중단합니다.

  3. Service 화면 입력

    /data/backup 마운트 후 Management Console의 Backup 영역 / Backup Service가 나타납니다. Settings → Backup에서 승인 일정(Daily 또는 custom cron)과 Number of snapshots를 설정하고 Save settings합니다. 기본 10개는 10일이 아닙니다. Include Pages·Skip search indices·복구 시 감사/관리 암호 옵션을 승인 범위와 대조합니다. Save settings는 서비스 재시작 가능성이 있는 변경이므로 적용 완료까지 확인합니다.

  4. 최초 백업

    변경 창의 I/O·비용·잔여 용량 승인 후 Backups → Backup Now를 선택합니다. 첫 실행은 full, 이후 증분 판단은 서비스가 수행합니다. CLI 대안은 아래와 같으며 UI와 동시에 실행하지 않습니다. Backup Service → Backup History에서 시작·종료·성공·snapshot ID·지속 시간을 기록합니다.

  5. 기존 Utilities 경로

    별도 호스트에서 호환 release archive·backup.config·GHE_HOSTNAME·GHE_DATA_DIR·일정을 검토합니다. GHES 관리 키 등록과 TCP 122를 승인한 다음 아래 host check와 백업을 수행합니다. Service로 이전할 때 설정 재입력 또는 공식 migration 절차를 사용하고 새 복구 시험 전 기존 사본을 폐기하지 않습니다.

조회 · 승인된 GHES 관리 셸 · bash
lsblk
findmnt /data/backup
df -h /data/backup
판정: 전용 장치·실제 mount·용량을 대조. mount 없음이나 화면 미노출은 초기화 완료가 아님.
승인 후 변경 · Backup Service가 구성된 GHES 관리 셸 · bash
ghe-backup
판정: 백업 쓰기·CPU/I/O 비용 발생. 성공 종료와 이력·snapshot·복구 가능성을 따로 확인.
승인 후 변경 · 기존 3.21 전용 Backup Utilities 호스트의 설치 디렉터리 · bash
./bin/ghe-host-check && ./bin/ghe-backup
판정: 연결 실패 시 키·호스트·TCP 122·지원 버전 해결 전 백업 실행 금지.

13.3 백업 상태 판정과 보관 범위

조회 · Backup Service 사용 GHES 관리 셸 · bash
tail -n 200 /var/log/github-backup/backup-verbose-YYYYMMDD.log
ls -l /data/user/common/backup_utils_in_progress
판정: 로그 파일명은 backup-verbose- 뒤 날짜 앞 하이픈 포함. YYYYMMDD는 해당 서버 로그 날짜로 치환. marker 존재는 진행 중 신호; 부재는 성공 증거가 아님.

실패/중첩이면 이전 작업의 진행·스토리지 접근·여유·지연·버전을 확인하고 중복 실행을 멈춥니다. marker를 지우거나 retention을 줄여 즉시 재실행하지 않습니다. 성공 후 자동 prune이 일어나므로 보존 변경도 승인 대상입니다. 매일 마지막 성공의 나이·지속 시간·누락 일정·잔여 용량을 확인하고 복구 시험을 주기적으로 재수행합니다.

데이터보호 범위 / 별도 정책복구 순서·판정
Git·DB·설정·Pages·검색snapshot 내용과 Include Pages / Skip search indices 실제 값 확인설정·메타데이터·저장소 검증; 검색 재색인 지연은 데이터 누락과 구분
Actions외부 logs·artifacts·blob은 GHES snapshot에 포함되지 않음외부 저장소를 준비·접근 검증 → Actions 설정 → GHES restore → 설정 적용 → Runner 재등록
PackagesGHES snapshot만으로 외부 blob 보호를 충족하지 않음; 저장소 사업자 백업·보존·복구 정책 필요복원한 blob과 GHES 메타데이터 시점 일치 확인 후 시험 package 다운로드/게시
네트워크·비밀대상 네트워크는 별도 준비; storage 인증·TLS·license·관리 암호 복원 영향 검토비밀은 vault/승인 채널 사용. 운영 설정 복원으로 시험 환경에서 운영 연결이 열리지 않도록 차단
복구: HA와 백업을 구분하고 복원 결과로 검증 동일한 로컬 Excalidraw 도형 데이터로 생성한 설명용 SVG. 편집기 내보내기가 아니며 HTML의 Clawpilot 테마를 상속합니다. 복구: HA와 백업을 구분하고 복원 결과로 검증 HA는 가용성을 개선하지만 삭제·손상에 대비한 독립 백업을 대체하지 않음 가용성 경로 · 복제 ≠ 백업 GHES 주 인스턴스 운영 데이터 HA 복제 인스턴스 복제 상태·전환 절차 확인 가용성을 위한 복제 복구 경로 · 백업과 외부 객체를 함께 보호 GHES 백업 스냅샷 버전별 지원 백업 방식 보존·접근 권한 분리 Actions / Packages 객체 외부 저장소 별도 보호 정합성·복구 범위 확인 격리된 복원 테스트 로그인·Git·객체 검증 복원 절차·증적 확보 수동 승인 운영 복구 실행 서비스 재검증 승인 후 운영 판단 복구 시점·데이터 손실 범위는 테스트로 확인 · RTO를 보장하거나 자동 장애 전환을 전제하지 않음 백업 엔진 토폴로지와 특정 버전의 신규 백업 기능은 여기서 가정하지 않음 · 실제 지원 문서 확인 설명용 개념도 · 실제 화면이나 고객 환경이 아님 · 연결은 주요 논리 흐름만 표시
설명용 개념도. HA, 시점 백업, 외부 객체 보호, 격리 복원은 다른 목적입니다. 복원 성공과 실측 복구 시간으로 운영 준비를 판단합니다.

13.4 격리 STAGING 복구 훈련

  1. 복구 선언·버전 선택

    사고 기준 T0, 선택 snapshot의 복구 가능 시점 T1, 복구 시작 T2를 UTC로 기록합니다. 같은 feature 또는 최대 두 feature 앞 대상까지 지원하며 최신→구버전 복원은 금지입니다. 예: 3.21 snapshot은 3.21/3.22 대상 가능, 3.22→3.21은 불가. 처음에는 같은 패치로 연습합니다.

  2. 격리 먼저

    새 STAGING 대상의 DNS·방화벽·관리 접근을 분리합니다. 운영 IdP/SCIM·webhook·SMTP·Runner·Actions/Packages 쓰기를 차단하고 시험용 목적지만 허용합니다. 서비스 시작 전에 차단을 적용합니다. snapshot 및 외부 저장소 사본을 준비하며 운영 storage 자격 증명을 시험에 그대로 복제하지 않습니다.

  3. Actions 호환성 게이트

    공식 Actions 복구는 원래 provider/credentials를 사전 구성하도록 안내합니다. 격리 복제 저장소의 주소·인증으로 메타데이터 호환성을 보장할 수 없으면 전체 Actions 복구 시험을 중단하고 지원팀과 격리 설계를 확인합니다. 운영 연결로 우회하거나 부분 시험을 전체 성공으로 보고하지 않습니다.

  4. maintenance·복원

    대상 maintenance를 켜고 백업 읽기 접근을 확인합니다. HA 구성 대상은 replication stop만으로 부족하며 공식 teardown 절차가 필요하므로 훈련은 새 standalone으로 시작합니다. 아래 선택 snapshot만 복원합니다. -c는 설정·인증서·license 덮어쓰기 옵션이지 DB 복원 여부가 아니므로 기본 예제에서 제외합니다.

승인 후 변경 · 운영과 격리된 STAGING Backup Service 복구 대상 관리 셸만 · bash
ghe-restore -s SNAPSHOT_TIMESTAMP
판정: 전체 대상 데이터 덮어쓰기. 대상·snapshot·버전·네트워크 격리·승인 2인 확인 없으면 실행 금지.
승인 후 변경 · 기존 3.21 Backup Utilities 호스트; 위 Service 명령 대신 사용하는 경로 · bash
./bin/ghe-restore -s SNAPSHOT_TIMESTAMP STAGING_HOSTNAME
판정: 대상은 승인된 격리 STAGING만. 대상 관리 키·버전·maintenance 확인 후 대화형 승인; -c 생략.
  1. 설정 검토·시작

    Management Console에서 네트워크·인증·TLS·storage·관리 암호 복원 영향을 확인 후 Save settings합니다. 네트워크 격리를 유지한 채 승인된 시험 IP exception list로 제한 접근을 열어 Git·issue·LFS·Pages·API·감사·검색·시험 Actions/Packages를 검증하고 Runner를 재등록합니다. 실패 시 restore-verbose-[timestamp].log를 제한 조회하며 HA 재구성은 standalone 성공 뒤에만 진행합니다.

  2. 측정·종료

    검증 완료 T3을 기록합니다. 관측 데이터 손실 구간은 T0−T1, 기술 복구 시간은 T3−T2, 사고 기준 서비스 회복 시간은 T3−T0입니다. 외부 blob의 일관된 복구 시점까지 포함해 승인 RPO/RTO와 비교합니다. 훈련 종료는 운영 트래픽 전환 승인이 아니며 결과·미복구 항목·후속 조치·사본 보존을 서명합니다.

13.5 HA 장애 전환은 별도 변경

replica는 hot standby이며 일반 사용자용 독립 읽기 전용 서버가 아닙니다. 일반 HA에서 replica 관리 콘솔은 replication mode를 표시하고 Git 요청은 primary로 전달될 수 있습니다. 노드 간 TCP 122·UDP 1194는 공식 포트 기준으로 범위 승인합니다. 연결·복제 상태를 확인하고 장애 선언 → 기존 primary fencing/maintenance → 미복제 손실 승인 → 수동 승격 → DNS/LB 전환 → 기능 검증 순서를 별도 실행계획으로 승인합니다. 여기에는 복사 가능한 운영 승격 명령을 넣지 않습니다. 되돌릴 때 양쪽 쓰기 허용 금지·재복제 계획이 필요합니다. 3.22는 cluster topology의 HA replication을 retired로 명시하며 일반 standalone HA와 다릅니다.

공식 근거: 3.21 Utilities·제거 예정 · 3.21 Service 구조 · 3.21 설정·NFS 주의 · 3.22 설정 · 이력·로그·marker · 설정 항목 · 복원 · Actions 외부 저장소 · Packages 외부 저장소 · HA 구조·트래픽 · 장애 전환 · 포트 · 3.22 GA·retired·알려진 문제

진행 기준 / 완료 증거: 백업 성공만으로 완료하지 않음. 외부 storage 포함 격리 복구와 손실/소요시간 검증, 3.22 전환 위험 해결.

Phase 14업그레이드·패치·안전한 복구

상세 참조 장 · STEP 12의 실행 순서·화면으로 돌아가기 →

담당: 변경 관리자·GHES·서비스 담당선행: 지원 경로·용량·STAGING·복구 게이트산출물: 버전/서명·검증·변경 종료 증거

14.1 기준일·지원 버전·변경 영향

featureGA지원 종료 / closing down운영 기준
3.212026-06-112027-06-11이 문서의 기본 운영 절차; 실행 시 최신 보안 patch·known issues 재검토
3.222026-09-082027-09-082026-09-19 현재 GA; 과거 9월 1일 RC 안내를 적용하지 않음
릴리스 선택 게이트

실행 당일 all-releases·해당 release notes·Security fixes/CVE·공식 다운로드를 재조회합니다. 특정 patch를 영구 최신으로 고정하지 않습니다. 3.21→3.22는 feature upgrade이며 대상은 소스보다 최대 두 feature 앞까지입니다(중간 feature 하나 생략 가능). Upgrade assistant에서 실제 source patch·target patch·플랫폼 경로를 확인하고 이전 migration/background jobs 완료를 검증합니다.

3.22 차이3.21 대비 필요한 조치
Backup Utilities3.21 문서의 3.22 제거 예정과 GA 노트의 확인 부재를 구분. Service 전환·복구 시험·지원 확인 전 진행 금지
복제·복원새 replication controller 및 controller 활성 시 ghe-restore storage 미복원 known issue 확인; 복구 검증 없는 승격 금지
Cluster HA3.22에서 해당 topology의 HA replication retired. 일반 HA 절차로 대체하지 말고 구조 전환 승인
업그레이드 단계3.22 노트에 phased execution 소개. 문서는 3.21+ 실행 가능 안내; 실제 source의 help로 지원 확인
연동·보안/repos 경로 충돌, pre-receive hook networking 기본 차단, 제거된 API 필드·Security 설정 API 점검
Actions·Dependabotvoting storage의 번들 Actions 설치 및 기존 Dependabot 일정 중단 known issues를 회귀 시험에 포함
관측성Collectd는 3.22와 이전 지원 창에서 지원; 제거 예고는 3.23. 3.22에서 이미 제거됐다고 쓰지 않음
업그레이드: 지원 경로와 회귀 검증을 통과해야 배포 동일한 로컬 Excalidraw 도형 데이터로 생성한 설명용 SVG. 편집기 내보내기가 아니며 HTML의 Clawpilot 테마를 상속합니다. 업그레이드: 지원 경로와 회귀 검증을 통과해야 배포 기준선 3.21 · 3.22는 해당 버전의 지원·변경 사항을 별도 확인 · RC는 운영용으로 선택하지 않음 1 · 현황 수집 실제 버전·패치 확인 구성·확장·용량 목록 2 · 지원 경로 확인 지원 GA·패치 선택 중간 업그레이드 검토 3 · 사전 검증 백업·복원 검증 격리 스테이징 리허설 4 · 변경 승인 유지보수 창 합의 담당·중단 기준 확정 준비: 왼쪽 → 오른쪽 실행·판정: 오른쪽 → 왼쪽 8 · 배포 게이트 결과·증적 승인 운영 인계 7 · 기능 회귀 검증 Git · Actions Packages 6 · ID 회귀 검증 SSO · SCIM 권한·로그인 5 · 업그레이드 승인된 지원 절차 진행 상태 확인 어느 단계든 실패 시 중단 → Support와 상황 확인 → 승인된 복원 계획에 따라 판단 무조건 다운그레이드 금지 · 복원은 별도 승인·검증 필요 · 소요 시간을 임의로 보장하지 않음 지원 GA 여부·업그레이드 경로·알려진 문제는 실행 시점의 버전별 공식 문서로 재확인 설명용 개념도 · 실제 화면이나 고객 환경이 아님 · 연결은 주요 논리 흐름만 표시
설명용 개념도. 버전·경로 확인부터 백업·staging·승인·변경 후 검증까지. 실패 시 무조건 이전 버전으로 덮어쓰는 방식이 아닙니다.

14.2 준비·다운로드·검증

  1. 영향·복구 승인

    변경 창·사용자 공지·서비스 중단 허용·담당·중단 시각·복구 승인자를 확정합니다. STAGING에서 SAML/LDAP·SCIM·GitHub Apps/OAuth·webhook·Runner·Actions·Packages·Code Security/Secret Protection·GEI 등 실제 사용 기능을 시험합니다. Cloud EMU 화면을 GHES로 대체하지 않습니다.

  2. 용량·백업 게이트

    공식 capacity 점검: CPU/메모리 통상 70% 미만, 디스크 비포화, 요청 큐 지속 200 미만, Aqueduct 적체 1~2시간 미만 및 data disk 최소 15% 여유를 확인합니다. 최근 백업·외부 storage·복구 시험과 feature 변경 직전 일관된 VM/디스크 snapshot 계획을 모두 준비합니다. 미충족이면 일정 연기합니다.

  3. 패키지 선택

    공식 releases → 대상 버전 Download → Upgrading → 실제 플랫폼의 .pkg를 선택합니다. URL·파일 크기·공식 SHA256(제공되는 artifact)·서명 검증 결과를 기록합니다. 게시되지 않은 hash를 만들지 않습니다. 3.21→3.22에 .hpkg나 Management Console의 patch 설치 화면을 사용하지 않습니다.

조회 · 업그레이드 전 source GHES 관리 셸 · bash
ghe-version
ghe-upgrade -h
판정: source patch/platform과 실제 지원 옵션 확인. --check / -c는 공개 문서로 의미 미확인: 사용하지 않음.
승인 후 변경 · 여유 공간·출력 파일명·다운로드가 승인된 source GHES 관리 셸 · bash
cd /home/admin && test ! -e APPROVED-UPGRADE.pkg &&
curl --fail --location --output APPROVED-UPGRADE.pkg 'OFFICIAL-PKG-URL' &&
sha256sum APPROVED-UPGRADE.pkg
판정: 기존 파일이 있으면 중단. 출력 SHA256을 해당 artifact의 공식 값과 직접 비교. 크기·hash 불일치 또는 다운로드 실패면 중단; 실패 시 남은 부분 파일은 재사용하지 않음.
승인 후 변경 · 다운로드·무결성 확인 후 source GHES 관리 셸 · bash
ghe-upgrade --verify /home/admin/APPROVED-UPGRADE.pkg
판정: 공개 hash가 없는 artifact는 공식 서명 검증 경로를 승인받아 진행. --verify는 공식 검증이지만 무쓰기 조회로 보장하지 않음. 서명 실패는 중단하며 설치로 우회하지 않음.

14.3 standalone feature upgrade 실행

  1. maintenance와 snapshot

    Management Console → Maintenance → Enable maintenance mode → now → Save. 진행 중 쓰기·작업 종료를 기다린 뒤 승인한 일관된 VM/디스크 snapshot을 생성·식별합니다. 전원이 켜진 VM의 임의 snapshot만으로 정합성을 가정하지 않습니다. maintenance 설정은 실제 서비스 변경입니다.

  2. 설치·재시작

    아래 명령의 패키지 경로와 표시된 target·서명을 다시 확인한 뒤 대화형 설치를 승인합니다. 새 root 영역 쓰기 및 자동 재시작을 예상하고 콘솔 접근을 유지합니다. 자동 yes 옵션은 넣지 않습니다. phased pre-upgrade는 준비 쓰기 작업이며 실제 지원 확인·별도 승인 시 표준 설치 대신 공식 절차를 택합니다.

승인 후 변경 · 모든 게이트가 통과된 standalone GHES 관리 셸; 먼저 STAGING · bash
ghe-upgrade /home/admin/APPROVED-UPGRADE.pkg
판정: 승인된 버전 설치·재시작. SSH 단절은 예상되지만 시간 초과 시 강제 재실행하지 않고 콘솔·로그 확인.
조회 · 재시작 후 GHES 관리 셸 · bash
ghe-version
ghe-service-list
tail -n 200 /data/user/common/ghe-config.log
판정: 목표 버전 및 자동 config apply 성공 확인. SSH 접속만으로 완료 아님; 자동 설정 실패 시 maintenance 유지, 근거 수집.
  1. 검증 후 개방

    migration·background jobs 상태와 custom firewall 규칙 재적용을 확인합니다. 자동 config apply를 이유 없이 재실행하지 않습니다. 제한된 시험 접근으로 로그인·clone/fetch/push·API·webhook·Actions/Packages·Security·백업 일정 및 첫 후속 백업을 확인합니다. IP exception list는 제한 접근 상태로 maintenance를 해제하는 기능이므로 별도 승인합니다.

  2. 정상화

    성공 증거·담당 서명 후 IP exception list를 사용했다면 해당 목록 기능을 비활성화·저장합니다. 사용하지 않았다면 Maintenance의 Enable maintenance mode를 해제·저장합니다. 시험 허용 목록 밖의 일반 사용자 접근도 재검증합니다. CPU/I/O·큐·오류율을 이전 기준선과 비교하며 관찰 창 종료 뒤 변경을 닫습니다. 실패하면 접근을 제한한 채 복구 분기로 갑니다.

14.4 patch·HA·cluster 분기와 실패 복구

분기절차 / 중단 기준
동일 feature hotpatch대상 patch의 자격을 확인. standalone은 automatic update checks 후 Updates → Install package 사용 가능. 일부 서비스 중단/재시작 가능하므로 모든 patch가 무중단이라고 약속하지 않음
일반 HA의 .pkg복제 정상 → primary maintenance → replica 복제 정지 → primary 업그레이드·config 성공 → replica 업그레이드 → 복제 시작·동기화 → 검증 후 개방. hotpatch는 별도 순서; 무조건 복제 정지하지 않음
cluster의 .pkg3.22 cluster HA retirement 해결이 선행. 공식 cluster 절차는 primary MySQL 이외 노드 먼저, primary MySQL 마지막 → cluster config apply/status → 정상 시 개방. 일반 HA의 primary-first와 혼용 금지
patch 롤백공식 --allow-patch-rollback은 이전 patch의 .pkg·재시작 등 조건이 있는 별도 변경. .hpkg나 feature downgrade 수단이 아니며 지원 문서·승인 없이 실행하지 않음
feature 실패3.22 DB를 3.21에 그대로 붙이는 downgrade 금지. 공식 rollback은 변경 전 일관된 snapshot 복구. 디스크 snapshot은 같은 release의 새 인스턴스에 복원; 대안은 변경 전 백업으로 호환 새 대상 복구
복구 실행 순서장애 선언·기존 primary 격리 → 승인된 snapshot/변경 전 백업 선택 → 외부 storage 시점 정합 → 격리 대상 복구·검증 → 손실 범위 승인 → DNS/LB 단일 쓰기 대상 전환. 실패 후 쓰기 손실은 별도 기록
미확인 사항을 남긴 채 통과시키지 않기

Backup Utilities 실제 제거/지원 상태, source 패치의 phased 옵션, 선택 artifact의 공개 checksum, 격리 Actions 복원 호환성, 3.22 replication-controller 복원 known issue 해결 여부는 실행 전 재확인 항목입니다. 조회한 문서는 업데이트될 수 있습니다. HA 자동화 문서의 순서와 package 절차가 다르면 임의 혼합하지 말고 선택한 토폴로지·버전의 공식 절차 및 지원 확인으로 변경계획을 확정합니다.

공식 근거: 전체 릴리스·GA/EOL · 3.21 release notes · 3.22 release notes · Upgrade assistant · 경로 요건 · 용량 · 개요·백업 · 3.21 package 절차 · 3.22 package·HA·phased · Hotpatch · Cluster · Snapshot · Maintenance·IP 예외 · 실패 복구 · 공식 다운로드 · 공식 화면: Maintenance · 공식 화면: Updates

진행 기준 / 완료 증거: 자동 설정·서비스·연동·복제·후속 백업 정상 및 관찰 창 통과. 미해결 known issue나 복구 불능이면 배포 중단.

부록 A. 증상 → 증거 → 조치 → 중단 기준

원인을 먼저 정하지 말고 실제 대상·실행 시각·인증 주체·HTTP/SCIM 상세부터 고정합니다. 아래 표는 가능한 원인의 분기이며 특정 환경에 발생했다고 확인한 장애 목록이 아닙니다.

증상먼저 확인할 증거안전한 다음 조치피할 행동
관리 콘솔이 열리지 않음관리 경로의 8443, DNS/IP, TLS, 해당 콘솔 인증 주체승인된 관리자 PC에서 연결을 확인. 웹 계정 암호와 콘솔 암호를 구분SCIM을 위해 관리 포트를 인터넷 전체에 공개하지 않음
SSH publickey 실패포트 122·사용자 admin·콘솔 등록 공개키·대응 개인키·호스트키 지문Git SSH22 키와 관리 SSH 키를 분리해 대조StrictHostKeyChecking=no 또는 키 원문 공유 금지
루트 디스크가 요청 용량의 절반총 가상 디스크와 현재 루트 파일시스템, 업그레이드 예약 공간공식 저장소 구조와 데이터 디스크를 각각 확인남은 파티션 삭제·포맷·임의 재분할 금지
SSO는 되는데 새 사용자가 없음SAML 성공과 SCIM 목적지·앱 할당·scope·실패 단계를 구분GHES용 앱의 Test Connection과 사용자별 provisioning event 확인Cloud의 성공을 Server 성공으로 대체하지 않음
Entra Test Connection timeoutEntra 서비스 관점의 DNS·연결점·NAT/LB/WAF·443·TLS같은 UTC의 경계·GHES 수신 로그로 단절 위치 확인사내 PC 접속 성공만으로 인바운드 개통 처리 금지
SCIM 401 / 403대상 호스트·PAT 소유자·classic/scim:enterprise·폐기/만료실제 응답 본문과 인증 주체를 대조 후 필요한 경우만 승인된 교체에러 하나로 scope 확대·관리자 역할 부여 금지
SCIM 404 / 405 / HTML 반환GHES /api/v3/scim/v2, Users 대소문자, SCIM 활성화, proxy path/methodGHEC enterprises/slug 및 관리 콘솔 주소 혼입 여부 확인리다이렉트·로그인 페이지를 API 성공으로 처리 금지
SCIM 400 / 409상세 속성 오류·중복 externalId/userName·역할·대상 기존 계정정규화·길이·신원 충돌을 해당 사용자에 한정해 확인모든 400=길이, 모든 409=동명이인으로 단정 금지
out of seats설치 파일 한도·실제 소비·발급 시점·Cloud 제품별 소비·요청 도착지파일 부족이 입증되면 새 키 경로 확인. SCIM 문구와 현상 차이는 Support 확인PAYG 또는 Connect가 키 한도를 자동 증설한다고 가정 금지
License 화면 오류HTTP 상태·UTC·request ID, ghe-license 정보와 licensing GET웹 오류와 SCIM 오류를 각각 수집하고 같은 사건인지 대조두 오류의 공통 원인을 로그 없이 확정하지 않음
사용자가 skipped직접/그룹 할당, scope/filter, 필수 속성·중첩 그룹·jobskipped 이유와 실제 대상 범위를 확인하고 제한된 파일럿Sync all로 확대하거나 전체 Restart로 밀어붙이지 않음
Owner 역할 미반영앱 관리 Owner와 app role, 역할 매핑·중복, 관리자 승격/강등 설정비상 접근·기존 Owner를 보호하고 현재 요청 roles 확인생성 오류를 Owner 부여로 우회하지 않음
사용자는 있는데 SAML 불가SAML objectidentifier ↔ SCIM externalId, active, 로그인 호스트·UTC올바른 신원 매칭·인증서·할당·조건부 액세스를 순서대로 확인UPN 일괄 수정·기존 계정 삭제·SAML 해제 금지
SAML 서명 / 시간 오류활성 인증서 지문·서명 방식·issuer/ACS·NTP 시간 오차인증서 교체 기록과 GHES 입력값, 시간 동기화 대조서명·MFA·TLS 검증 해제로 우회하지 않음
팀 멤버·권한이 예상과 다름SCIM 그룹과 연결 팀, 직접 가입·다른 팀·private/internal관련 모든 경로와 시험 사용자의 실제 허용/거부 비교base permission None이 internal까지 숨긴다고 가정 금지
Connect가 켜졌는데 계정 없음Cloud/Server 각 앱·계정과 Connect 기능 설정사용량 보고 연결과 별도 SAML·SCIM 구성을 분리Cloud 사용자를 Server로 자동 복제한다고 가정 금지
Cloud/Server 중복 집계동일 사용자 이메일, 연결 Enterprise, 마지막 성공 sync, 제품 구분사용량 보고·동일 사용자 연결을 확인. 동기화는 별도 데이터 전송이메일 변경으로 기존 신원을 즉시 조작하지 않음
Blob container 확인만 통과실제 인증 모드, upload 요청 코드·caller IP·Storage 로그Shared Key/SAS/OIDC, 네트워크·권한을 구분하고 쓰기 단계 확인Container presence Passed를 전체 성공으로 처리 금지
Blob KeyBasedAuthenticationNotPermittedShared Key 정책과 현재 credentials 방식인증 방식을 보안 정책·지원 조건에 맞춰 변경 승인진단 중 Shared Key 금지 정책 해제 금지
Blob AuthorizationFailureStorage firewall, public access, 실제 egress IP, PE/DNSGHES 서비스 위치·실제 경로와 로그를 대조관리자 PC az login 성공을 GHES 인증 증거로 대체 금지
Blob OIDC token exchange 실패issuer/subject/audience·tenant/client·federated credential·공개 JWKSGHES 저장소 OIDC와 workflow OIDC 구분repo:ORG/REPO subject를 GHES 저장소용으로 사용하지 않음
Runner queued / offlineonline/busy, label, runner group·저장소 허용, outbound/TLS정확한 전용 시험 runner와 job 조건을 확인승인되지 않은 운영 runner·관리자 자격증명으로 우회 금지
action ref를 찾지 못함번들/동기화된 action ref·정책·연결된 외부 action 경로승인된 commit/ref가 해당 GHES에서 사용 가능한지 확인인터넷 전체 개방·검증 안 된 action 설치 금지
artifact v4 계열 실패GHES 호환 action 계열과 실제 설치 ref현재 GHES 지원되는 v3-node20 등의 공식 경로 확인GitHub.com 예제의 artifact v4+를 무조건 복사하지 않음
Packages push / pull 실패GHES registry hostname·package ecosystem·PAT/GITHUB_TOKEN·repo 권한·storageActions 저장소 설정과 Packages 저장소 설정을 별개로 대조ghcr.io 또는 Cloud 인증을 GHES registry와 혼용하지 않음
백업 없음 / 복원 실패실제 백업 방식·버전·snapshot·외부 storage·격리 대상Backup History와 해당 방식 로그, 지원되는 복원 버전 범위 확인운영 대상으로 시험 restore·staging의 운영 Blob 쓰기 금지
업그레이드 경로 / 버전 불일치현재/목표 버전·공식 업그레이드 경로·백업 방식 전환지원되는 GA·중간 버전·최신 보안 패치와 릴리스별 변경 확인RC 운영 설치·DB downgrade·무승인 재실행 금지
앱 할당 뒤 새 사용자가 없음GHES용 앱·Tenant URL, 자동 주기 진행/대기와 Stopped, 사용자별 event실패 단계·scope·대상 ID를 확인하고 승인된 단일 사용자로 검증할당 즉시 생성된다고 가정하거나 전체 재프로비저닝하지 않음
GHEC에 무작위처럼 보이는 계정이 있음Cloud/Server 호스트·객체 ID·externalId·생성 시각동일 신원인지 새 객체인지 실제 ID와 감사 이벤트로 대조표시 이름만으로 새 신원 생성 확정·기존 계정 삭제 금지
License Sync / Enable 후 키 한도가 그대로설치 키 한도·사용량·동기화 목적·실제 발급 파일사용량 보고와 새 키 발급·적용 절차를 분리Sync/Enable을 키 용량 자동 증설로 해석 금지
Connect cannot connect / cannot verify원문 메시지·UTC·DNS/TLS·outbound·proxy·실제 시간 오차일반 연결 실패를 분기별 확인하고 서버·경계 로그 대조NTP 확정 또는 Disable 후 재연결을 기본 처방으로 삼지 않음
넓은 outbound·proxy 우회 후 연결됨임시 허용 범위·실제 egress·proxy 미시험 항목·승인 기한최소 통신 범위와 proxy 경유 재시험·임시 규칙 회수 계획 기록임시 성공을 운영 최종 구성 완료로 처리 금지
기본 로그 위치를 모르거나 grep 결과 없음production·HTTP·journal, 실제 실패 UTC·처리 노드·보존·필터제한된 최근 행부터 보고 정확한 시간 창과 경로를 교차 확인무출력을 서버 미호출로 단정하거나 원문 로그를 채팅에 공유 금지
새 키 업로드·재시작 후 정상화 관측변경 전후 키 한도·SCIM 상세·요청 상태·실제 사용자 결과변경 후 관측과 근본 원인 입증을 분리해 기록재시작을 기본 처방 또는 단일 원인의 증명으로 삼지 않음
지원 문의에 함께 남길 항목

실제 GHES 버전, 정확한 대상 API/화면 경로, UTC와 시간대, 변경 전후·마지막 정상 시각, 영향 사용자 수와 정상/실패 차이, request/job/event ID, 비밀값을 뺀 응답, 이미 실행한 승인 변경. HAR·SAML assertion·토큰·쿠키·라이선스 파일은 일반 채팅이나 공개 티켓에 붙이지 않습니다.

로그·주의사항 빠른 조회

질문 / 증상제한된 조회 절차판정 주의
기본 로그는 어디에?production.log 최근 100행·짧은 followCtrl+C는 조회기 종료이며 서비스 중지가 아님
실패 시각의 기록 찾기최근 20분·필수 UTC 구간 입력START_UTC·END_UTC에 실제 실패 시작·끝 설정; 미설정·빈 값이면 조회 중단
SCIM 요청이 도착했는가?nginx HTTP·제한된 journal앱·GHES Tenant URL·노드/LB·시각·보존·필터 확인 전 무출력으로 단정 금지
200이면 사용자가 생성됐는가?메서드별 원본 HTTP 상태GET 200 ≠ POST 201 생성; Entra Change ID ≠ 자동 GHES request ID
생성·정지·이름 변경 확인audit·exceptions·nginx errorsource/target ID와 시각 대조; 감사 기록은 HTTP 수신 로그를 대체하지 않음
라이선스 UI·최근 설정 적용 오류콘솔 unicorn·ghe-config 별도 분기SCIM 기본 출발점과 분리; 업로드·재시작 뒤 정상화 관측만으로 원인 확정 금지
어느 서비스인지 불명확내장 ghe-logs-tail 선택 관찰출력량이 많고 행 제한 없음; 짧게 보고 Ctrl+C
Connect 일반 오류·임시 outbound 성공주의사항 조회표NTP 단정·Disable 재연결 기본 처방 금지; proxy 재시험 전 최종 완료 아님

공식 근거: GHES SCIM · 시스템 로그 · Storage 403 · Support 자료

부록 B. 자주 섞이는 개념과 위험한 지름길

1. GHES = Cloud EMU가 아님

호스트·사용자·앱·SSO·SCIM은 각각. Cloud shortcode_admin 절차를 appliance에 복사하지 않습니다.

2. Git22 / 관리122 / 콘솔8443

각각 다른 목적과 권한입니다. SCIM 인바운드는 HTTPS443입니다.

3. 내 PC 접속 ≠ Entra 도달

공개 DNS·승인된 진입점·TLS·실제 서비스 요청 로그로 확인합니다.

4. OIDC 이름이 같아도 다름

사용자 SSO, Actions workflow federation, GHES 외부 스토리지 federation을 구분합니다.

5. 파일 용량 ≠ 현재 사용량

유효한 라이선스와 여유 좌석은 별개. Connect 보고가 기존 파일 한도를 늘리지 않습니다.

6. Owner를 주면 해결? 금지

앱 할당·매핑·scope와 실제 오류를 확인합니다. 전원 Owner는 해결책이 아닙니다.

7. 같은 이메일 ≠ 같은 객체

SCIM externalId·SAML objectidentifier·기존 계정 연결을 확인합니다. 새 객체를 기존 계정으로 오인하지 않습니다.

8. 자원 수치 = 성능 보장? 아님

권장표와 실제 워크로드·IOPS·지연·자동화 부하를 함께 봅니다.

9. HA = 백업? 아님

복제는 잘못된 변경도 전파합니다. 별도 시점 백업과 복원 시험이 필요합니다.

10. 백업 완료 = 복원 가능? 아님

복원 버전·외부 객체·비밀정보·실제 복구 시간을 확인해야 합니다.

11. 저장소·runner의 신뢰 경계

기여자의 코드가 runner에서 실행됩니다. 전용 계정·네트워크·runner group·환경 비밀을 제한합니다.

12. 인증서 검증 해제 금지

TLS 실패를 -k나 호스트키 우회로 숨기지 말고 FQDN·체인·신뢰·시간을 고칩니다.

13. Copy → Paste → Production 금지

실행 위치·버전·대상·권한·변경 승인을 확인하고 한 번에 한 변수만 바꿉니다.

14. AI 기능의 코드 전송 경계

GHES 안에 저장소가 있어도 Copilot 등 별도 AI 도구가 외부로 컨텍스트를 보낼 수 있습니다.

15. root filesystem 절반의 의미

업그레이드 예약 공간을 장애로 오인해 파티션을 변경하지 않습니다.

16. 완료·미확인·N/A를 구분

파일럿 로그인 성공만으로 Blob·Runner·Packages·백업까지 완료 처리하지 않습니다.

17. 할당 직후 없음 ≠ 생성 실패 확정

자동 주기와 Stopped·scope·사용자별 이벤트를 구분하고 전체 재프로비저닝을 기본 진단으로 삼지 않습니다.

18. Connect 일반 오류 ≠ NTP 확정

제안된 점검과 입증된 원인을 구분합니다. Disable 후 재연결 대신 실제 연결 경로·시간 오차를 확인합니다.

19. 임시 outbound 성공 ≠ 운영 완료

최소 허용·proxy 경유 재시험·임시 규칙 회수 책임과 기한이 남아 있습니다.

20. 최근 N행·grep ≠ 전체 로그

시간 필터·보존·노드·경로를 대조합니다. 무출력은 서버 호출 부재의 증명이 아닙니다.

21. 읽기 전용 로그 ≠ 공개 자료

개인정보·토큰·SAML·쿠키가 있을 수 있습니다. 원문 제한 보관과 공유본 비식별화·승인은 별개입니다.

22. 변경 뒤 정상 ≠ 근본 원인 입증

키 업로드·재시작과 정상화의 시간적 관계만으로 원인을 확정하거나 재시작을 반복 처방하지 않습니다.

부록 C. 구축·운영 인수 체크리스트

체크는 이 문서에서의 로컬 표시이며 실제 운영 완료 증명이 아닙니다. 자동 저장되지 않습니다. 실제 결과·UTC·작업자·승인·증거 위치를 별도로 기록하고 미사용 기능은 N/A 사유를 남깁니다.

설계·라이선스

네트워크·설치

신원·권한

선택 기능·연결

운영·인수

일반 운영 점검: 제한된 로그·신원·연결 검증

결과 기록 양식

로컬 세션·파일 · 승인된 인수 기록 · text
Check item:
Target / installed version:
Operator / approver / UTC:
Expected result:
Observed result / event or request ID:
PASS / FAIL / NOT TESTED / N/A with reason:
Evidence location (restricted):
Approved change and recovery decision:
Owner / support case / next checkpoint:
판정: 비밀값은 제외하고 각 완료 조건의 실제 근거를 연결합니다.

부록 D. 공식 문서·이미지 출처

2026-09-19 기본 절차에 2026-09-21 운영상 주의점의 공식 근거를 보강한 참조 목록입니다. 기존 모든 기능을 새로 감사했다는 뜻은 아닙니다. 명령·UI는 해당 버전·권한에 맞춰 현장에서 검증해야 합니다. 개념도·공식 예제 화면은 실제 환경의 구성·성공 결과를 증명하지 않습니다.

  • 공식 원문 출처https://docs.github.com/en/enterprise-server@3.21/billing/how-tos/manage-server-licenses/upload-new-license
  • 공식 원문 출처https://learn.microsoft.com/en-us/entra/identity/saas-apps/github-enterprise-server-provisioning-tutorial
  • 공식 원문 출처https://learn.microsoft.com/en-us/exchange/permissions-exo/application-rbac#new-service-principal
  • 공식 원문 출처https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/assign-user-or-group-access-portal
  • 공식 원문 출처https://learn.microsoft.com/en-us/entra/identity/saas-apps/github-enterprise-server-tutorial
  • GHES 3.21 SAML·SCIM 제품 기준https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/provisioning-user-accounts-with-scim/configuring-authentication-and-provisioning-with-entra-id
  • 공식 원문 출처https://learn.microsoft.com/en-us/entra/identity/app-provisioning/provision-on-demand
  • 공식 원문 출처https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-provisioning-logs
  • 공식 원문 출처https://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-github-connect/enabling-automatic-user-license-sync-for-your-enterprise
  • 공식 원문 출처https://docs.github.com/en/enterprise-server@3.21/admin/managing-github-actions-for-your-enterprise/enabling-github-actions-for-github-enterprise-server/enabling-github-actions-with-azure-blob-storage
  • 공식 원문 출처https://docs.github.com/en/enterprise-server@3.21/actions/how-tos/manage-runners/self-hosted-runners/add-runners
  • GHES 시스템 구조https://docs.github.com/en/enterprise-server@3.21/admin/overview/system-overview
  • Cloud·Server 병용https://docs.github.com/en/enterprise-server@3.21/billing/concepts/enterprise-billing/combined-enterprise-use
  • EMU 공식 안내https://docs.github.com/en/enterprise-cloud@latest/admin/concepts/identity-and-access-management/enterprise-managed-users
  • 전체 릴리스·지원 기간https://docs.github.com/en/enterprise-server@3.22/admin/all-releases
  • 3.21 릴리스 노트https://docs.github.com/en/enterprise-server@3.21/admin/release-notes
  • 지원 플랫폼 색인https://docs.github.com/en/enterprise-server@3.21/admin/installing-your-enterprise-server/setting-up-a-github-enterprise-server-instance
  • VMwarehttps://docs.github.com/en/enterprise-server@3.21/admin/installing-your-enterprise-server/setting-up-a-github-enterprise-server-instance/installing-github-enterprise-server-on-vmware
  • Azurehttps://docs.github.com/en/enterprise-server@3.21/admin/installing-your-enterprise-server/setting-up-a-github-enterprise-server-instance/installing-github-enterprise-server-on-azure
  • AWShttps://docs.github.com/en/enterprise-server@3.21/admin/installing-your-enterprise-server/setting-up-a-github-enterprise-server-instance/installing-github-enterprise-server-on-aws
  • Hyper-Vhttps://docs.github.com/en/enterprise-server@3.21/admin/installing-your-enterprise-server/setting-up-a-github-enterprise-server-instance/installing-github-enterprise-server-on-hyper-v
  • OpenStack KVMhttps://docs.github.com/en/enterprise-server@3.21/admin/installing-your-enterprise-server/setting-up-a-github-enterprise-server-instance/installing-github-enterprise-server-on-openstack-kvm
  • GCPhttps://docs.github.com/en/enterprise-server@3.21/admin/installing-your-enterprise-server/setting-up-a-github-enterprise-server-instance/installing-github-enterprise-server-on-google-cloud-platform
  • Actions 최소 자원·외부 저장소https://docs.github.com/en/enterprise-server@3.21/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/getting-started-with-github-actions-for-github-enterprise-server
  • 관리 셸 지원 범위https://docs.github.com/en/enterprise-server@3.21/admin/administering-your-instance/administering-your-instance-from-the-command-line/accessing-the-administrative-shell-ssh
  • 라이선스 파일https://docs.github.com/en/enterprise-server@3.21/billing/concepts/enterprise-billing/ghes-license-files
  • Cloud 소비 사용자·예외https://docs.github.com/en/enterprise-cloud@latest/billing/reference/github-license-users
  • 사용량 동기화 방향https://docs.github.com/en/enterprise-server@3.21/billing/how-tos/manage-server-licenses/sync-license-usage
  • enterprise.github.com/downloadhttps://enterprise.github.com/download
  • 공식 다운로드 분기·UIhttps://docs.github.com/en/enterprise-server@3.21/billing/how-tos/manage-server-licenses/download-your-license
  • Console 인증https://docs.github.com/en/enterprise-server@3.21/admin/administering-your-instance/administering-your-instance-from-the-web-ui/accessing-the-management-console
  • Console 계정 유형https://docs.github.com/en/enterprise-server@3.21/admin/administering-your-instance/administering-your-instance-from-the-web-ui/managing-access-to-the-management-console
  • ghe-license info / checkhttps://docs.github.com/en/enterprise-server@3.21/admin/administering-your-instance/administering-your-instance-from-the-command-line/command-line-utilities#ghe-license
  • 라이선스 GET APIhttps://docs.github.com/en/enterprise-server@3.21/rest/enterprise-admin/licensing#get-license-information
  • 파일·PAYG 좌석 기준https://docs.github.com/en/billing/concepts/enterprise-billing/ghes-license-files
  • 다운로드·노란 배너https://docs.github.com/en/enterprise-cloud@latest/billing/how-tos/manage-server-licenses/download-your-license
  • 공식 포트·HA·Connecthttps://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-network-settings/network-ports
  • Connect 연결 경계https://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-github-connect/about-github-connect
  • runner 통신https://docs.github.com/en/enterprise-server@3.21/actions/reference/runners/self-hosted-runners#communication
  • GHES SCIM 도달성https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/provisioning-user-accounts-with-scim/configuring-scim-provisioning-for-users
  • hostname 변경 경고https://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-network-settings/configuring-the-hostname-for-your-instance
  • DNS resolverhttps://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-network-settings/configuring-dns-nameservers
  • 하위 도메인·SANhttps://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/hardening-security-for-your-enterprise/enabling-subdomain-isolation
  • TLS·LB 제한https://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/hardening-security-for-your-enterprise/configuring-tls
  • NTPhttps://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-network-settings/configuring-time-synchronization
  • Entra IP Rangeshttps://learn.microsoft.com/en-us/entra/identity/app-provisioning/use-scim-to-provision-users-and-groups#ip-ranges
  • Entra Test Connection·주기·온디맨드https://learn.microsoft.com/en-us/entra/identity/app-provisioning/use-scim-to-provision-users-and-groups#integrate-your-scim-endpoint-with-the-microsoft-entra-provisioning-service
  • Connect의 세 호스트·Cloud IP allowlisthttps://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-github-connect/enabling-github-connect-for-githubcom
  • 아웃바운드 프록시·Actions 제한https://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-network-settings/configuring-an-outbound-web-proxy-server
  • 읽기 도구·시스템 정보https://docs.github.com/en/enterprise-server@3.21/admin/administering-your-instance/administering-your-instance-from-the-command-line/command-line-utilities
  • 3.21 SAML 설정https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/using-saml-for-enterprise-iam/configuring-saml-single-sign-on-for-your-enterprise
  • 3.21 built-in 인증https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/understanding-iam-for-enterprises/allowing-built-in-authentication-for-users-outside-your-provider
  • Console 계정 경계https://docs.github.com/en/enterprise-server@3.21/admin/administering-your-instance/administering-your-instance-from-the-web-ui
  • 3.21 setup 계정 Owner 승격https://docs.github.com/en/enterprise-server@3.21/admin/managing-accounts-and-repositories/managing-users-in-your-enterprise/promoting-or-demoting-a-site-administrator
  • Entra 초기·증분·범위·격리https://learn.microsoft.com/en-us/entra/identity/app-provisioning/how-provisioning-works
  • Entra 로그·Change ID·Stepshttps://learn.microsoft.com/en-us/entra/identity/monitoring-health/howto-analyze-provisioning-logs
  • Cloud EMU 퇴사·복귀·감사 이벤트https://docs.github.com/en/enterprise-cloud@latest/admin/managing-iam/provisioning-user-accounts-with-scim/deprovisioning-and-reinstating-users
  • Cloud·Server 라이선스 소비 기준https://docs.github.com/en/billing/reference/github-license-users
  • 3.21 기존 사용자 매칭https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/provisioning-user-accounts-with-scim/user-provisioning-with-scim-on-ghes
  • 3.21 SCIM API·paginationhttps://docs.github.com/en/enterprise-server@3.21/rest/enterprise-admin/scim
  • 3.21 단일 쓰기 원천·가용 좌석https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/provisioning-user-accounts-with-scim/provisioning-users-and-groups-with-scim-using-the-rest-api
  • 3.21 신원·프로비저닝 오류https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/understanding-iam-for-enterprises/troubleshooting-identity-and-access-management-for-your-enterprise
  • 3.21 퇴사·복귀https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/provisioning-user-accounts-with-scim/deprovisioning-and-reinstating-users
  • GHES 좌석 기준https://docs.github.com/en/enterprise-server@3.21/billing/reference/github-license-users
  • 3.17 릴리스https://docs.github.com/en/enterprise-server@3.17/admin/release-notes
  • 3.14 릴리스https://docs.github.com/en/enterprise-server@3.14/admin/release-notes
  • 3.21 IdP 그룹과 조직 팀https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/provisioning-user-accounts-with-scim/managing-team-memberships-with-identity-provider-groups
  • 3.21 저장소 가시성https://docs.github.com/en/enterprise-server@3.21/repositories/creating-and-managing-repositories/about-repositories
  • 3.21 CODEOWNERS 강제 조건https://docs.github.com/en/enterprise-server@3.21/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
  • 3.21 보호 브랜치https://docs.github.com/en/enterprise-server@3.21/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches
  • 3.21 연결 메타데이터의 주간 시각https://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-github-connect/about-github-connect#data-transmitted-when-github-connect-is-enabled
  • 3.21 SCIM 생성과 가용 라이선스https://docs.github.com/en/enterprise-server@3.21/admin/managing-iam/provisioning-user-accounts-with-scim/provisioning-users-and-groups-with-scim-using-the-rest-api#provisioning-users-with-the-rest-api
  • 3.21 사용량 기반 결제https://docs.github.com/en/enterprise-server@3.21/billing/concepts/enterprise-billing/usage-based-licenses
  • 3.21 이메일 중복 제거https://docs.github.com/en/enterprise-server@3.21/billing/reference/enterprise-license-troubleshooting
  • Cloud 현재 사용량 UIhttps://docs.github.com/en/enterprise-cloud@latest/billing/how-tos/manage-plan-and-licenses/view-enterprise-usage
  • Copilot 현재 제품 범위https://docs.github.com/en/copilot/get-started/plans
  • Cloud agent 현재 호스팅 조건https://docs.github.com/en/copilot/concepts/agents/cloud-agent/about-cloud-agent
  • 3.22 Azure 인증https://docs.github.com/en/enterprise-server@3.22/admin/managing-github-actions-for-your-enterprise/enabling-github-actions-for-github-enterprise-server/enabling-github-actions-with-azure-blob-storage
  • Azure 403https://learn.microsoft.com/en-us/troubleshoot/azure/azure-storage/blobs/authentication/storage-troubleshoot-403-errors
  • Federated credential CLIhttps://learn.microsoft.com/en-us/cli/azure/ad/app/federated-credential
  • StorageBlobLogs 스키마https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/storagebloblogs
  • OS별 서비스https://docs.github.com/en/enterprise-server@3.21/actions/how-tos/manage-runners/self-hosted-runners/configure-the-application
  • 통신·ephemeralhttps://docs.github.com/en/enterprise-server@3.21/actions/reference/runners/self-hosted-runners
  • 조직 runner APIhttps://docs.github.com/en/enterprise-server@3.21/rest/actions/self-hosted-runners#list-self-hosted-runners-for-an-organization
  • Actions 공급https://docs.github.com/en/enterprise-server@3.21/admin/managing-github-actions-for-your-enterprise/managing-access-to-actions-from-githubcom/about-using-actions-in-your-enterprise
  • Upload GHES 지원https://github.com/actions/upload-artifact#ghes-support
  • Upload Node20 refhttps://github.com/actions/upload-artifact/blob/v3-node20/action.yml
  • Download Node20 refhttps://github.com/actions/download-artifact/blob/v3-node20/action.yml
  • 3.21 Azure Packageshttps://docs.github.com/en/enterprise-server@3.21/admin/configuring-packages/enabling-github-packages-with-azure-blob-storage
  • 3.22 Azure Packageshttps://docs.github.com/en/enterprise-server@3.22/admin/configuring-packages/enabling-github-packages-with-azure-blob-storage
  • 자원·생태계https://docs.github.com/en/enterprise-server@3.21/admin/configuring-packages/getting-started-with-github-packages-for-your-enterprise
  • Ecosystem toggleshttps://docs.github.com/en/enterprise-server@3.21/admin/configuring-packages/configuring-package-ecosystem-support-for-your-enterprise
  • Container registry·인증https://docs.github.com/en/enterprise-server@3.21/packages/working-with-a-github-packages-registry/working-with-the-container-registry
  • 백업 서비스https://docs.github.com/en/enterprise-server@3.21/admin/backing-up-and-restoring-your-instance/about-the-backup-service-for-github-enterprise-server
  • Backup Utilities 전환https://docs.github.com/en/enterprise-server@3.21/admin/backing-up-and-restoring-your-instance/configuring-backups-on-your-instance
  • Docker pull·레이어 캐시https://docs.docker.com/reference/cli/docker/image/pull/
  • Business 전용 enterprisehttps://docs.github.com/en/copilot/concepts/enterprise/about-enterprise-accounts-for-copilot-business
  • Cloud/Server 청구 구분https://docs.github.com/en/billing/concepts/enterprise-billing/combined-enterprise-use
  • Cloud 정책·AI controlshttps://docs.github.com/en/copilot/concepts/enterprise/policies
  • 좌석 할당https://docs.github.com/en/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-access/grant-access
  • Cloud CLI 인증https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/authenticate-copilot-cli
  • 네트워크 allowlisthttps://docs.github.com/en/copilot/reference/copilot-allowlist-reference
  • BYOKhttps://docs.github.com/en/copilot/concepts/models/bring-your-own-key
  • SDK BYOKhttps://docs.github.com/en/copilot/how-tos/copilot-sdk/auth/byok
  • Content exclusionhttps://docs.github.com/en/copilot/concepts/context/content-exclusion
  • 문맥과 책임 있는 사용https://docs.github.com/en/copilot/responsible-use/chat
  • 3.22 릴리스https://docs.github.com/en/enterprise-server@3.22/admin/release-notes
  • 3.22 CLI technical previewhttps://docs.github.com/en/enterprise-server@3.22/admin/github-copilot/copilot-cli/set-up-and-use-copilot-cli
  • 3.21 Monitorhttps://docs.github.com/en/enterprise-server@3.21/admin/monitoring-and-managing-your-instance/monitoring-your-instance/about-the-monitor-dashboards
  • 임계값https://docs.github.com/en/enterprise-server@3.21/admin/monitoring-and-managing-your-instance/monitoring-your-instance/recommended-alert-thresholds
  • 스토리지 구조https://docs.github.com/en/enterprise-server@3.21/admin/overview/system-overview#storage-architecture
  • 로그·회전https://docs.github.com/en/enterprise-server@3.21/admin/monitoring-and-managing-your-instance/monitoring-your-instance/about-system-logs
  • 지원 자료https://docs.github.com/en/enterprise-server@3.21/support/contacting-github-support/providing-data-to-github-support
  • 감사 보존https://docs.github.com/en/enterprise-server@3.21/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/configuring-the-audit-log-for-your-enterprise
  • 조직 감사 180일https://docs.github.com/en/enterprise-server@3.21/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/reviewing-the-audit-log-for-your-organization
  • 감사 스트리밍https://docs.github.com/en/enterprise-server@3.21/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise
  • Sysloghttps://docs.github.com/en/enterprise-server@3.21/admin/monitoring-activity-in-your-enterprise/exploring-user-activity-in-your-enterprise/log-forwarding
  • SMTPhttps://docs.github.com/en/enterprise-server@3.21/admin/configuring-settings/configuring-user-applications-for-your-enterprise/configuring-email-for-notifications
  • 라이선스 APIhttps://docs.github.com/en/enterprise-server@3.21/rest/enterprise-admin/licensing
  • Security 청구https://docs.github.com/en/enterprise-server@3.21/billing/concepts/product-billing/github-advanced-security
  • 3.21 설정·NFS 주의https://docs.github.com/en/enterprise-server@3.21/admin/backing-up-and-restoring-your-instance/configuring-the-backup-service
  • 3.22 설정https://docs.github.com/en/enterprise-server@3.22/admin/backing-up-and-restoring-your-instance/configuring-the-backup-service
  • 이력·로그·markerhttps://docs.github.com/en/enterprise-server@3.21/admin/backing-up-and-restoring-your-instance/creating-and-monitoring-backups
  • 설정 항목https://docs.github.com/en/enterprise-server@3.21/admin/backing-up-and-restoring-your-instance/backup-service-settings-reference
  • 복원https://docs.github.com/en/enterprise-server@3.21/admin/backing-up-and-restoring-your-instance/restoring-from-a-backup
  • Actions 외부 저장소https://docs.github.com/en/enterprise-server@3.21/admin/backing-up-and-restoring-your-instance/restoring-with-github-actions-enabled
  • HA 구조·트래픽https://docs.github.com/en/enterprise-server@3.21/admin/monitoring-and-managing-your-instance/configuring-high-availability/about-high-availability-configuration
  • 장애 전환https://docs.github.com/en/enterprise-server@3.21/admin/monitoring-and-managing-your-instance/configuring-high-availability/initiating-a-failover-to-your-replica-appliance
  • Upgrade assistanthttps://support.github.com/enterprise/server-upgrade
  • 경로 요건https://docs.github.com/en/enterprise-server@3.22/admin/upgrading-your-instance/preparing-to-upgrade/upgrade-requirements
  • 용량https://docs.github.com/en/enterprise-server@3.22/admin/upgrading-your-instance/preparing-to-upgrade/check-system-capacity-before-upgrading
  • 개요·백업https://docs.github.com/en/enterprise-server@3.22/admin/upgrading-your-instance/preparing-to-upgrade/overview-of-the-upgrade-process
  • 3.21 package 절차https://docs.github.com/en/enterprise-server@3.21/admin/upgrading-your-instance/performing-an-upgrade/upgrading-with-an-upgrade-package
  • 3.22 package·HA·phasedhttps://docs.github.com/en/enterprise-server@3.22/admin/upgrading-your-instance/performing-an-upgrade/upgrading-with-an-upgrade-package
  • Hotpatchhttps://docs.github.com/en/enterprise-server@3.22/admin/upgrading-your-instance/performing-an-upgrade/upgrading-with-a-hotpatch
  • Clusterhttps://docs.github.com/en/enterprise-server@3.22/admin/monitoring-and-managing-your-instance/configuring-clustering/upgrading-a-cluster
  • Snapshothttps://docs.github.com/en/enterprise-server@3.22/admin/upgrading-your-instance/preparing-to-upgrade/taking-a-snapshot
  • Maintenance·IP 예외https://docs.github.com/en/enterprise-server@3.21/admin/administering-your-instance/configuring-maintenance-mode/enabling-and-scheduling-maintenance-mode
  • 실패 복구https://docs.github.com/en/enterprise-server@3.22/admin/upgrading-your-instance/troubleshooting-upgrades/restoring-from-a-failed-upgrade
  • 공식 다운로드https://enterprise.github.com/releases
  • 공식 화면: Maintenancehttps://docs.github.com/assets/images/enterprise/management-console/maintenance-tab.png
  • 공식 화면: Updateshttps://docs.github.com/assets/images/enterprise/management-console/updates-tab.png
원본과 산출물

새 HTML에 이미지·그림·스타일·스크립트를 내장했습니다. 개념도는 설명용이며, 편집 가능한 Excalidraw 원본은 제작 소스와 함께 보관합니다. 체크는 로컬 문서 표시이며 새로고침하면 초기화됩니다. 변경 승인·성공 증거 없이 완료를 선언하지 않습니다.

GitHub Enterprise Server 범용 구축·운영 가이드 · 2026-09-21 개정 / 기본 절차 2026-09-19 · 절차 기준 3.21 / 3.22 등 목표 버전은 지원·보안 패치·백업·업그레이드 변경을 별도 확인.