Skip to content

Commit de03452

Browse files
authored
fix(core): Fix missing encryption key check on workers (n8n-io#14603)
1 parent 981eaf0 commit de03452

File tree

4 files changed

+34
-19
lines changed

4 files changed

+34
-19
lines changed

packages/cli/src/commands/worker.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { Flags, type Config } from '@oclif/core';
33

44
import config from '@/config';
55
import { N8N_VERSION, inTest } from '@/constants';
6-
import { WorkerMissingEncryptionKey } from '@/errors/worker-missing-encryption-key.error';
76
import { EventMessageGeneric } from '@/eventbus/event-message-classes/event-message-generic';
87
import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus';
98
import { LogStreamingEventRelay } from '@/events/relays/log-streaming.event-relay';
@@ -58,8 +57,6 @@ export class Worker extends BaseCommand {
5857
}
5958

6059
constructor(argv: string[], cmdConfig: Config) {
61-
if (!process.env.N8N_ENCRYPTION_KEY) throw new WorkerMissingEncryptionKey();
62-
6360
if (config.getEnv('executions.mode') !== 'queue') {
6461
config.set('executions.mode', 'queue');
6562
}

packages/core/src/instance-settings/__tests__/instance-settings.test.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ import { mock } from 'jest-mock-extended';
22
jest.mock('node:fs', () => mock<typeof fs>());
33
import * as fs from 'node:fs';
44

5-
import { InstanceSettings } from '@/instance-settings';
6-
import { InstanceSettingsConfig } from '@/instance-settings/instance-settings-config';
7-
import { Logger } from '@/logging/logger';
8-
import { mockInstance } from '@test/utils';
5+
import type { Logger } from '@/logging/logger';
6+
7+
import { InstanceSettings } from '../instance-settings';
8+
import { InstanceSettingsConfig } from '../instance-settings-config';
9+
import { WorkerMissingEncryptionKey } from '../worker-missing-encryption-key.error';
910

1011
describe('InstanceSettings', () => {
1112
const userFolder = '/test';
12-
process.env.N8N_USER_FOLDER = userFolder;
1313
const settingsFile = `${userFolder}/.n8n/config`;
1414

1515
const mockFs = mock(fs);
16-
const logger = mockInstance(Logger);
16+
const logger = mock<Logger>();
1717

1818
const createInstanceSettings = (opts?: Partial<InstanceSettingsConfig>) =>
1919
new InstanceSettings(
@@ -27,6 +27,9 @@ describe('InstanceSettings', () => {
2727
beforeEach(() => {
2828
jest.resetAllMocks();
2929
mockFs.statSync.mockReturnValue({ mode: 0o600 } as fs.Stats);
30+
31+
process.argv[2] = 'main';
32+
process.env = { N8N_USER_FOLDER: userFolder };
3033
});
3134

3235
describe('If the settings file exists', () => {
@@ -184,6 +187,11 @@ describe('InstanceSettings', () => {
184187
},
185188
);
186189
});
190+
191+
it("should throw on a worker process, if encryption key isn't set via env", () => {
192+
process.argv[2] = 'worker';
193+
expect(() => createInstanceSettings()).toThrowError(WorkerMissingEncryptionKey);
194+
});
187195
});
188196

189197
describe('constructor', () => {

packages/core/src/instance-settings/instance-settings.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Memoized } from '@/decorators';
99
import { Logger } from '@/logging/logger';
1010

1111
import { InstanceSettingsConfig } from './instance-settings-config';
12+
import { WorkerMissingEncryptionKey } from './worker-missing-encryption-key.error';
1213

1314
const nanoid = customAlphabet(ALPHABET, 16);
1415

@@ -46,15 +47,15 @@ export class InstanceSettings {
4647

4748
readonly enforceSettingsFilePermissions = this.loadEnforceSettingsFilePermissionsFlag();
4849

49-
private settings = this.loadOrCreate();
50+
private settings: Settings;
5051

5152
/**
5253
* Fixed ID of this n8n instance, for telemetry.
5354
* Derived from encryption key. Do not confuse with `hostId`.
5455
*
5556
* @example '258fce876abf5ea60eb86a2e777e5e190ff8f3e36b5b37aafec6636c31d4d1f9'
5657
*/
57-
readonly instanceId = this.generateInstanceId();
58+
readonly instanceId: string;
5859

5960
readonly instanceType: InstanceType;
6061

@@ -68,6 +69,8 @@ export class InstanceSettings {
6869
: 'main';
6970

7071
this.hostId = `${this.instanceType}-${nanoid()}`;
72+
this.settings = this.loadOrCreate();
73+
this.instanceId = this.generateInstanceId();
7174
}
7275

7376
/**
@@ -177,6 +180,7 @@ export class InstanceSettings {
177180
* settings file with an auto-generated encryption key.
178181
*/
179182
private loadOrCreate(): Settings {
183+
const encryptionKeyFromEnv = process.env.N8N_ENCRYPTION_KEY;
180184
if (existsSync(this.settingsFile)) {
181185
const content = readFileSync(this.settingsFile, 'utf8');
182186
this.ensureSettingsFilePermissions();
@@ -189,7 +193,7 @@ export class InstanceSettings {
189193

190194
const { encryptionKey, tunnelSubdomain } = settings;
191195

192-
if (process.env.N8N_ENCRYPTION_KEY && encryptionKey !== process.env.N8N_ENCRYPTION_KEY) {
196+
if (encryptionKeyFromEnv && encryptionKey !== encryptionKeyFromEnv) {
193197
throw new ApplicationError(
194198
`Mismatching encryption keys. The encryption key in the settings file ${this.settingsFile} does not match the N8N_ENCRYPTION_KEY env var. Please make sure both keys match. More information: https://docs.n8n.io/hosting/environment-variables/configuration-methods/#encryption-key`,
195199
);
@@ -198,19 +202,25 @@ export class InstanceSettings {
198202
return { encryptionKey, tunnelSubdomain };
199203
}
200204

205+
if (!encryptionKeyFromEnv) {
206+
if (this.instanceType === 'worker') {
207+
throw new WorkerMissingEncryptionKey();
208+
}
209+
210+
if (!inTest) {
211+
this.logger.info(
212+
`No encryption key found - Auto-generating and saving to: ${this.settingsFile}`,
213+
);
214+
}
215+
}
216+
201217
mkdirSync(this.n8nFolder, { recursive: true });
202218

203-
const encryptionKey = process.env.N8N_ENCRYPTION_KEY ?? randomBytes(24).toString('base64');
219+
const encryptionKey = encryptionKeyFromEnv ?? randomBytes(24).toString('base64');
204220

205221
const settings: Settings = { encryptionKey };
206222

207223
this.save(settings);
208-
209-
if (!inTest && !process.env.N8N_ENCRYPTION_KEY) {
210-
this.logger.info(
211-
`No encryption key found - Auto-generated and saved to: ${this.settingsFile}`,
212-
);
213-
}
214224
this.ensureSettingsFilePermissions();
215225

216226
return settings;

0 commit comments

Comments
 (0)