내부 builder 인증과 실행 허용 목록 및 자원 경계를 적용한다
This commit is contained in:
@@ -14,6 +14,14 @@ export const validateComposeModel = (model, mode) => {
|
||||
const caddy = model?.services?.caddy;
|
||||
if (!builder) errors.push('builder service is missing');
|
||||
if (!caddy) errors.push('caddy service is missing');
|
||||
for (const [name, service] of [['runtime', runtime], ['builder', builder]]) {
|
||||
const target = '/run/secrets/release_builder_token';
|
||||
if (service?.environment?.RELEASE_BUILDER_TOKEN_FILE !== target) errors.push(`${name} must use the mounted builder token file`);
|
||||
const mount = (service?.volumes ?? []).find((entry) => entry.target === target);
|
||||
if (!mount || mount.type !== 'bind' || mount.read_only !== true) errors.push(`${name} builder token mount must be read-only`);
|
||||
}
|
||||
if ((builder?.ports ?? []).length) errors.push('builder must not publish host ports');
|
||||
|
||||
|
||||
const requiredImageEnvironment = {
|
||||
GATEWAY_IMAGE_UPLOAD_SECRET_FILE: '/run/secrets/image_upload_core2026_secret',
|
||||
@@ -120,7 +128,7 @@ export const validateComposeModel = (model, mode) => {
|
||||
errors.push('builder Rayon thread count must be between 1 and 4');
|
||||
}
|
||||
for (const name of Object.keys(builder.environment ?? {})) {
|
||||
if (/(?:SECRET|TOKEN|PASSWORD|DATABASE_URL|REDIS_URL)/i.test(name)) {
|
||||
if (name !== 'RELEASE_BUILDER_TOKEN_FILE' && /(?:SECRET|TOKEN|PASSWORD|DATABASE_URL|REDIS_URL)/i.test(name)) {
|
||||
errors.push(`builder must not receive sensitive environment variable ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user