내부 builder 인증과 실행 허용 목록 및 자원 경계를 적용한다

This commit is contained in:
2026-10-09 04:31:44 +09:00
parent 6d05c01a76
commit f78ab77850
13 changed files with 979 additions and 205 deletions
+44
View File
@@ -293,3 +293,47 @@ Caddy cache matcher의 적용·제외 경계는 다음처럼 비밀값 없이
```sh
node --test test/caddy-cache-policy.test.mjs
```
## Builder 인증 전환
`RELEASE_BUILDER_TOKEN_FILE`은 runtime과 builder에만 read-only로 mount하는 전용
무작위 token 파일입니다. `.env`에는 파일 경로만 넣습니다. Git 제외 경로에
mode 0600으로 생성하고 DB/Redis/OAuth secret을 재사용하지 않습니다.
```sh
mkdir -p secrets
(umask 077; set -C; openssl rand -hex 32 > secrets/release_builder_token)
# .env: RELEASE_BUILDER_TOKEN_FILE=./secrets/release_builder_token
```
기존 파일이 있으면 위 생성 명령으로 교체하지 않습니다. `scripts/check.sh`는
파일의 존재·권한과 양쪽 read-only mount를 검사합니다. Builder의 `/healthz`는
인증 없이 조회할 수 있지만 `/v1/builds`는 `x-release-builder-token`이 필요합니다.
이 token은 HTTP header에만 쓰며 명령 payload와 progress/child env에는 넣지 않습니다.
허용 명령은 Core package의 frozen install·build·Prisma generate와 고정 frontend
materialize script입니다. 실제 cwd/cache symlink, Node heap/thread 옵션도 검증합니다.
하나의 job을 실행하며 실행·대기·body 읽기 합계 3개, body 256 KiB/5초,
job 30분, NDJSON frame 512 KiB/stream 64 MiB와 pending response 1 MiB를 상한으로
둡니다. 과부하 429와 잘못된 인증 401은 child를 만들지 않습니다. 연결 중단과
deadline은 실행 process group을 종료하고 실제 종료까지 자리를 유지합니다.
Builder는 신뢰하는 repository/dependency script를 실행합니다. 이 인증을 임의
repository code에 대한 OS sandbox로 해석하지 않습니다. builder 전용 token 파일은
같은 builder의 build code가 읽을 수 있지만 다른 운영 credential은 이 service와
child env에 제공하지 않습니다.
기존 stack에는 token mount·환경 경로부터 추가하고 **기존 builder를 유지한 상태**로
새 Core의 controller와 Gateway를 먼저 갱신합니다. 이후 인증을 강제하는 새 builder와
인증 헤더를 보내는 새 Docker bootstrap client를 함께 build·재생성합니다. 새 builder를
먼저 적용하면 구형 client가 401로 실패합니다. Core의 `docs/release-operations.md`에
같은 전환 순서를 기록했습니다. 현재 운영 기기에서 실행할 때는 SSH 재접속 없이
해당 host의 wrapper를 직접 사용합니다.
```sh
node --test test/*.test.mjs
```
실제 HTTP 테스트는 인증/UTF-8 body/대기열/취소/deadline/느린 소비자를 확인하며
synthetic executable의 실제 자식 process와 종료도 검증합니다. 공개 운영의 적용
근거는 해당 환경에서 별도로 확인해야 합니다.