Quick Reference
node \
--permission \
--allow-fs-read="/app/config" \
--allow-fs-write="/app/tmp" \
--allow-net \
server.jsif (!process.permission?.has("fs.read", "/app/config/app.json")) {
throw new Error("설정 파일 읽기 권한 없음");
}--permission은 파일, 네트워크, 자식 프로세스, worker 등 접근을 기본 거부로 전환합니다. 필요한 파일 경로만 --allow-fs-read와 --allow-fs-write로 열고, 네트워크가 필요한 경우에는 --allow-net을 명시합니다. 현재 --allow-net은 호스트별 allowlist가 아니라 네트워크 접근 전체를 허용하므로, 대상 호스트 제한은 방화벽이나 프록시 같은 별도 경계에서 처리합니다.
권한 경계
먼저 머릿속에 잡아 둘 기본형은 아래입니다.
- 권한 모델 활성화:
node --permission app.js - 파일 읽기 허용:
--allow-fs-read - 파일 쓰기 허용:
--allow-fs-write - 네트워크 전체 허용:
--allow-net - 런타임 확인:
process.permission.has(scope, reference)
보안 옵션보다 실행 경계로 읽는다
Permission Model의 핵심은 앱이 접근 가능한 파일, 네트워크, 자식 프로세스 범위를 실행 시점에 줄이는 것입니다. Node 20에서 도입됐고, 22.13+/23.5+부터는 더 이상 experimental이 아닙니다.
기본값은 닫고 필요한 것만 연다
--permission을 켜면 허용하지 않은 리소스는 막힙니다. 필요한 파일 경로와 실행 기능을 먼저 인벤토리하는 작업이 중요합니다. 네트워크는 현재 호스트 단위로 좁힐 수 없으므로 --allow-net을 주는 순간 모든 네트워크 접근을 허용한다는 점을 따로 판단해야 합니다.
process.permission.has()는 더 좋은 오류 메시지를 위한 카드다
권한이 없어 예외가 터지기 전에, 어떤 권한이 비어 있는지 더 명확하게 보여주고 싶을 때 쓸 만합니다.
이 모델은 보안 경계라기보다 seat belt에 가깝다
권한 모델은 신뢰한 코드가 실수로 너무 넓은 자원에 접근하는 일을 줄이는 데 유용합니다. 반대로 악성 코드까지 완전히 막는 강한 샌드박스로 읽으면 과대평가가 됩니다.
worker와 자식 런타임의 경계를 따로 확인한다
권한 모델은 worker thread에 자동 상속되지 않습니다. 자식 Node 프로세스도 별도 런타임이므로 실행 인자와 환경 변수에 --permission 설정을 명시했는지 확인해야 합니다. 실행 경계가 늘어나면 각 경계의 권한을 따로 검증합니다.
적용 전에는 audit mode로 필요한 접근을 찾는다
node --permission-audit은 접근을 막지 않고, 막혔을 접근을 diagnostics_channel로 발행합니다. 운영 적용 전에 필요한 파일·네트워크·자식 프로세스 권한을 찾는 용도로 먼저 실행하고, 확인된 범위만 enforce mode에 넣는 순서가 안전합니다.
언제 켤까
체크포인트
- 파일 읽기 허용:
--allow-fs-read - 파일 쓰기 허용:
--allow-fs-write - 네트워크 허용:
--allow-net - 자식 프로세스 허용:
--allow-child-process - worker 허용:
--allow-worker - 런타임 확인:
process.permission.has(...) - 강한 샌드박스가 아니라 실행 seat belt로 읽기
- 배포 전에는
--permission-audit으로 필요한 권한을 확인
주의할 점
--permission을 켜지 않으면 이 모델은 적용되지 않는다. 또 이 기능을 강한 보안 샌드박스로 과대평가하면 운영 판단이 어긋날 수 있다. 공식 문서도 악성 코드를 막는 보안 경계로 보지 말라고 설명하므로, 필요한 권한을 좁히는 실행 seat belt로 읽는 편이 맞다.
참고 링크
1 sources