refactor(core): Rename inbound-secrets module to runtime-credentials (no-changelog) (#30889)

This commit is contained in:
Andreas Fitzek 2026-05-21 15:08:57 +02:00 committed by GitHub
parent 222c14aea1
commit 7cfee608ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 67 additions and 65 deletions

View File

@ -44,7 +44,7 @@ describe('eligibleModules', () => {
'instance-version-history',
'encryption-key-manager',
'oauth-jwe',
'inbound-secrets',
'runtime-credentials',
'mcp-registry',
]);
});
@ -76,7 +76,7 @@ describe('eligibleModules', () => {
'instance-version-history',
'encryption-key-manager',
'oauth-jwe',
'inbound-secrets',
'runtime-credentials',
'mcp-registry',
'instance-ai',
]);

View File

@ -55,7 +55,7 @@ export class ModuleRegistry {
'instance-version-history',
'encryption-key-manager',
'oauth-jwe',
'inbound-secrets',
'runtime-credentials',
'mcp-registry',
];

View File

@ -30,7 +30,7 @@ export const MODULE_NAMES = [
'instance-version-history',
'encryption-key-manager',
'oauth-jwe',
'inbound-secrets',
'runtime-credentials',
] as const;
export type ModuleName = (typeof MODULE_NAMES)[number];

View File

@ -1,26 +0,0 @@
import type { ModuleInterface } from '@n8n/decorators';
import { BackendModule } from '@n8n/decorators';
import { Container } from '@n8n/di';
import { RuntimeCredentialProxyService } from '@/services/runtime-credential-proxy.service';
function isFeatureFlagEnabled(): boolean {
return process.env.N8N_ENV_FEAT_INBOUND_SECRETS === 'true';
}
@BackendModule({ name: 'inbound-secrets' })
export class InboundSecretsModule implements ModuleInterface {
async init() {
if (!isFeatureFlagEnabled()) return;
const { InboundSecretsService } = await import('./inbound-secrets.service');
Container.get(InboundSecretsService).init();
await import('./inbound-secrets-context-hook');
await import('./inbound-secrets.config');
const { InboundSecretsAccessService } = await import('./inbound-secrets-access.service');
Container.get(RuntimeCredentialProxyService).registerProvider(
Container.get(InboundSecretsAccessService),
);
}
}

View File

@ -2,7 +2,7 @@ import { mock } from 'jest-mock-extended';
import type { Cipher } from 'n8n-core';
import type { IRunExecutionData } from 'n8n-workflow';
import { InboundSecretsAccessService } from '../inbound-secrets-access.service';
import { RuntimeCredentialsAccessService } from '../runtime-credentials-access.service';
const ENCRYPTED_BLOB = 'encrypted-blob-placeholder';
@ -13,9 +13,9 @@ const buildRunExecutionData = (secureArtifacts: unknown): IRunExecutionData =>
},
}) as unknown as IRunExecutionData;
describe('InboundSecretsAccessService', () => {
describe('RuntimeCredentialsAccessService', () => {
const cipher = mock<Cipher>();
const service = new InboundSecretsAccessService(cipher);
const service = new RuntimeCredentialsAccessService(cipher);
const plaintextArtifacts = JSON.stringify({
version: 1,

View File

@ -3,12 +3,12 @@ import type { MockProxy } from 'jest-mock-extended';
import { mock } from 'jest-mock-extended';
import type { INode, INodeExecutionData } from 'n8n-workflow';
import { InboundSecretContextHook } from '../inbound-secrets-context-hook';
import type { InboundSecretsService, StripResult } from '../inbound-secrets.service';
import { RuntimeCredentialsContextHook } from '../runtime-credentials-context-hook';
import type { RuntimeCredentialsService, StripResult } from '../runtime-credentials.service';
describe('InboundSecretContextHook', () => {
let service: MockProxy<InboundSecretsService>;
let hook: InboundSecretContextHook;
describe('RuntimeCredentialsContextHook', () => {
let service: MockProxy<RuntimeCredentialsService>;
let hook: RuntimeCredentialsContextHook;
const buildOptions = (triggerItems: INodeExecutionData[] | null): ContextEstablishmentOptions =>
({
@ -28,8 +28,8 @@ describe('InboundSecretContextHook', () => {
): StripResult => ({ triggerItems, artifactsByAlias }) as StripResult;
beforeEach(() => {
service = mock<InboundSecretsService>();
hook = new InboundSecretContextHook(service);
service = mock<RuntimeCredentialsService>();
hook = new RuntimeCredentialsContextHook(service);
});
it('forwards items and trigger type to service.strip and emits the alias-keyed contextUpdate', async () => {

View File

@ -1,17 +1,17 @@
import { Container } from '@n8n/di';
import { InboundSecretsModule } from '../inbound-secrets.module';
import { RuntimeCredentialsModule } from '../runtime-credentials.module';
describe('InboundSecretsModule', () => {
let module: InboundSecretsModule;
describe('RuntimeCredentialsModule', () => {
let module: RuntimeCredentialsModule;
beforeEach(() => {
Container.reset();
module = new InboundSecretsModule();
module = new RuntimeCredentialsModule();
});
afterEach(() => {
delete process.env.N8N_ENV_FEAT_INBOUND_SECRETS;
delete process.env.N8N_ENV_FEAT_RUNTIME_CREDENTIALS;
});
describe('init', () => {
@ -20,7 +20,7 @@ describe('InboundSecretsModule', () => {
});
it('loads without error when the feature flag is on', async () => {
process.env.N8N_ENV_FEAT_INBOUND_SECRETS = 'true';
process.env.N8N_ENV_FEAT_RUNTIME_CREDENTIALS = 'true';
await expect(module.init()).resolves.toBeUndefined();
});
});

View File

@ -3,19 +3,19 @@ import type { MockProxy } from 'jest-mock-extended';
import { mock } from 'jest-mock-extended';
import type { IDataObject, INodeExecutionData } from 'n8n-workflow';
import type { InboundSecretsConfig } from '../inbound-secrets.config';
import type { SensitiveFieldRules } from '../inbound-secrets.schemas';
import { InboundSecretsService } from '../inbound-secrets.service';
import type { RuntimeCredentialsConfig } from '../runtime-credentials.config';
import type { SensitiveFieldRules } from '../runtime-credentials.schemas';
import { RuntimeCredentialsService } from '../runtime-credentials.service';
const item = (json: IDataObject): INodeExecutionData => ({ json });
describe('InboundSecretsService', () => {
let service: InboundSecretsService;
let config: MockProxy<InboundSecretsConfig>;
describe('RuntimeCredentialsService', () => {
let service: RuntimeCredentialsService;
let config: MockProxy<RuntimeCredentialsConfig>;
beforeEach(() => {
config = mock<InboundSecretsConfig>();
service = new InboundSecretsService(mockLogger(), config);
config = mock<RuntimeCredentialsConfig>();
service = new RuntimeCredentialsService(mockLogger(), config);
});
describe('init', () => {

View File

@ -6,7 +6,7 @@ import { toSecureArtifacts } from 'n8n-workflow';
import { RuntimeCredentialProvider } from '@/services/runtime-credential-proxy.service';
@Service()
export class InboundSecretsAccessService implements RuntimeCredentialProvider {
export class RuntimeCredentialsAccessService implements RuntimeCredentialProvider {
constructor(private readonly cipher: Cipher) {}
async getRuntimeCredential(

View File

@ -6,16 +6,16 @@ import {
IContextEstablishmentHook,
} from '@n8n/decorators';
import { InboundSecretsService } from './inbound-secrets.service';
import { RuntimeCredentialsService } from './runtime-credentials.service';
@ContextEstablishmentHook({
alwaysExecute: true,
})
export class InboundSecretContextHook implements IContextEstablishmentHook {
constructor(private readonly inboundSecretsService: InboundSecretsService) {}
export class RuntimeCredentialsContextHook implements IContextEstablishmentHook {
constructor(private readonly runtimeCredentialsService: RuntimeCredentialsService) {}
hookDescription: HookDescription = {
name: 'InboundSecretContextHook',
name: 'RuntimeCredentialsContextHook',
};
isApplicableToTriggerNode(_nodeType: string): boolean {
@ -24,7 +24,7 @@ export class InboundSecretContextHook implements IContextEstablishmentHook {
}
async execute(options: ContextEstablishmentOptions): Promise<ContextEstablishmentResult> {
const { triggerItems, artifactsByAlias } = this.inboundSecretsService.strip(
const { triggerItems, artifactsByAlias } = this.runtimeCredentialsService.strip(
options.triggerItems ?? [],
options.triggerNode.type,
);

View File

@ -1,7 +1,7 @@
import { Config, Env } from '@n8n/config';
@Config
export class InboundSecretsConfig {
export class RuntimeCredentialsConfig {
@Env('N8N_SECURITY_SENSITIVE_FIELD_RULES')
sensitiveFieldRules: string = '{}';
}

View File

@ -0,0 +1,28 @@
import type { ModuleInterface } from '@n8n/decorators';
import { BackendModule } from '@n8n/decorators';
import { Container } from '@n8n/di';
import { RuntimeCredentialProxyService } from '@/services/runtime-credential-proxy.service';
function isFeatureFlagEnabled(): boolean {
return process.env.N8N_ENV_FEAT_RUNTIME_CREDENTIALS === 'true';
}
@BackendModule({ name: 'runtime-credentials' })
export class RuntimeCredentialsModule implements ModuleInterface {
async init() {
if (!isFeatureFlagEnabled()) return;
const { RuntimeCredentialsService } = await import('./runtime-credentials.service');
Container.get(RuntimeCredentialsService).init();
await import('./runtime-credentials-context-hook');
await import('./runtime-credentials.config');
const { RuntimeCredentialsAccessService } = await import(
'./runtime-credentials-access.service'
);
Container.get(RuntimeCredentialProxyService).registerProvider(
Container.get(RuntimeCredentialsAccessService),
);
}
}

View File

@ -2,12 +2,12 @@ import { Logger } from '@n8n/backend-common';
import { Service } from '@n8n/di';
import { INodeExecutionData, ISecureArtifactsV1, jsonParse } from 'n8n-workflow';
import { InboundSecretsConfig } from './inbound-secrets.config';
import { RuntimeCredentialsConfig } from './runtime-credentials.config';
import {
SensitiveFieldRules,
sensitiveFieldRulesSchema,
ValueLookupPath,
} from './inbound-secrets.schemas';
} from './runtime-credentials.schemas';
import { extractAndClear } from './path-traversal';
type ArtifactItem = ISecureArtifactsV1['artifacts'][string];
@ -18,12 +18,12 @@ export type StripResult = {
};
@Service()
export class InboundSecretsService {
export class RuntimeCredentialsService {
private sensitiveFieldRules: SensitiveFieldRules = {};
constructor(
private readonly logger: Logger,
private readonly config: InboundSecretsConfig,
private readonly config: RuntimeCredentialsConfig,
) {}
init() {