본문으로 건너뛰기

GitHub App 연결

GitHub App은 TRUSCA가 세분화된 저장소별 접근에 사용하는 자격증명입니다. 예를 들어 곧 추가될 자동 리메디에이션(의존성 버전 상향 PR 자동 생성) 흐름에서 사용됩니다. PAT(Personal Access Token)와 달리 GitHub App은 다음과 같습니다.

  • 설치 가능 — 조직/저장소 단위로 설치하고 세분화된 권한(contents + pull_requests: write)을 부여합니다.
  • 단기 토큰 — TRUSCA는 작업마다 새 설치 액세스 토큰을 발급하며, 장기 비밀은 서버 밖으로 나가지 않습니다.
  • 멀티테넌트 — 각 팀이 자신의 App을 독립적으로 등록·관리합니다.
대상

team_admin은 자기 팀의 자격증명을 등록·폐기하고 설치를 연결합니다. super_admin은 모든 팀을 관리할 수 있습니다. developer는 자기 팀 자격증명을 조회만 할 수 있고 변경은 불가합니다.

API 전용 관리

현재 릴리스에서는 GitHub App 자격증명을 등록하는 포털 내 폼이 없습니다 — 아래에 나열된 등록 / 연결 엔드포인트가 유일한 관리 경로입니다. team_admin 용 UI 는 로드맵 항목입니다. 그때까지 등록의 감사 흔적은 감사 로그 에서 확인할 수 있습니다(암호화된 컬럼은 *** 로 마스킹).

저장되는 항목

등록된 자격증명은 하나의 팀에 속한 행이며 다음을 보관합니다.

필드저장 형태비고
app_id평문GitHub App 숫자 id (App JWT의 iss).
app_slug평문(선택)사람이 읽는 App slug.
개인 키(PEM)Fernet 암호문App 개인 키. 등록 시 1회만 입력받으며 어떤 엔드포인트도 반환하지 않습니다.
Webhook 시크릿Fernet 암호문(선택)App Webhook HMAC 시크릿.

평문 개인 키는 등록 요청 본문에서만 받으며 PostgreSQL에 기록되기 전에 암호화됩니다. 어떤 조회 엔드포인트도 키나 암호문을 반환하지 않으며, 응답에는 메타데이터와 has_private_key / has_webhook_secret 불리언만 담깁니다.

저장 시 암호화

개인 키와 Webhook 시크릿은 저장 전에 Fernet(AES-128-CBC + HMAC-SHA256)으로 암호화되고, 단일 토큰 발급 작업 동안에만 메모리에서 복호화됩니다.

암호화 키는 런타임에 결정됩니다.

  1. GITHUB_APP_ENCRYPTION_KEY — URL-safe base64로 인코딩된 32바이트 Fernet 키. 프로덕션에서는 반드시 설정하세요. 다음으로 생성합니다.

    from cryptography.fernet import Fernet
    print(Fernet.generate_key().decode())
  2. 미설정 시 SECRET_KEY에서 결정론적으로 키를 파생해 로컬/개발 환경이 추가 설정 없이 동작합니다. 파생 키 사용 시 구조화된 WARNING 로그가 남습니다.

신중한 회전

파생 키는 SECRET_KEY와 운명을 공유합니다. 전용 GITHUB_APP_ENCRYPTION_KEY 없이 운영하면 SECRET_KEY를 회전할 때 저장된 모든 GitHub App 자격증명을 복호화할 수 없게 됩니다 — App을 모두 재등록해야 합니다. 프로덕션에서는 독립적으로 회전 가능한 전용 GITHUB_APP_ENCRYPTION_KEY를 설정하세요.

복호화할 수 없는 자격증명(키가 회전된 경우)은 사용 시 깔끔한 오류로 표면화되며, 키가 절대 누출되지 않습니다.

감사 로그

자격증명 등록·폐기·재연결은 audit_logs 행을 남깁니다. private_key_encryptedwebhook_secret_encrypted 컬럼은 감사 diff에서 ***로 마스킹되어 자격증명 자료가 감사 추적에 남지 않습니다.

폐기는 API Key와 동일하게 소프트 삭제(revoked_at 설정)입니다. 자격증명은 즉시 사용 불가가 되지만 행은 포렌식 조회를 위해 보존됩니다.

설치 옵트인

자격증명만으로는 TRUSCA가 프로젝트 저장소를 다룰 권한이 생기지 않습니다. 팀이 명시적으로 설치(계정/저장소)를 TRUSCA 프로젝트에 연결해야 합니다. 옵트인 대상 프로젝트는 자격증명과 같은 팀 소유여야 하며, 팀 간 연결은 거부됩니다.

엔드포인트

모든 엔드포인트는 JWT 인증을 요구하며 오류 시 RFC 7807 application/problem+json을 반환합니다. 접두사: /v1/github-app-credentials.

메서드경로역할용도
POST/v1/github-app-credentials?team_id=…team_admin자격증명 등록(201). 개인 키 미반환.
GET/v1/github-app-credentials멤버호출자가 볼 수 있는 자격증명 목록.
GET/v1/github-app-credentials/{id}멤버단일 자격증명 메타데이터 조회.
DELETE/v1/github-app-credentials/{id}team_admin폐기(소프트 삭제). 멱등.
POST/v1/github-app-credentials/{id}/installationsteam_admin설치 연결/옵트인. 재연결 시 멱등.
GET/v1/github-app-credentials/{id}/installations멤버자격증명의 설치 목록.
DELETE/v1/github-app-credentials/{id}/installations/{installation_id}team_admin설치 연결 해제. 멱등.

비멤버가 자격증명 id를 탐색하면 403이 아닌 404(존재 숨김)를 받아 id 열거를 막습니다.

관련 설정

변수기본값용도
GITHUB_APP_ENCRYPTION_KEY(SECRET_KEY에서 파생)저장 시 자격증명 암호화용 Fernet 키.
GITHUB_API_URLhttps://api.github.comGitHub REST 베이스. GitHub Enterprise Server는 재정의.