diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md
index 52fbdd607b6c92118c3a15dc3c29cbfa2520e8f8..af593128fbcc0d756660b9c0d5c86166bcc414e0 100644
--- a/docs/usage/self-hosted-configuration.md
+++ b/docs/usage/self-hosted-configuration.md
@@ -672,6 +672,58 @@ By default, Renovate does not autodiscover repositories that are mirrors.
 
 Change this setting to `true` to include repositories that are mirrors as Renovate targets.
 
+## inheritConfig
+
+When you enable this option, Renovate will look for the `inheritConfigFileName` file in the `inheritConfigRepoName` repository before processing a repository, and read this in as config.
+
+If the repository is in a nested organization or group on a supported platform such as GitLab, such as `topGroup/nestedGroup/projectName` then Renovate will look in `topGroup/nestedGroup/renovate-config`.
+
+If `inheritConfig` is `true` but the inherited config file does _not_ exist then Renovate will proceed without warning.
+If the file exists but cannot be parsed, then Renovate will raise a config warning issue and abort the job.
+
+The inherited config may include all valid repository config and these config options:
+
+- `bbUseDevelopmentBranch`
+- `onboarding`
+- `onboardingBranch`
+- `onboardingCommitMessage`
+- `onboardingConfig`
+- `onboardingConfigFileName`
+- `onboardingNoDeps`
+- `onboardingPrTitle`
+- `onboardingRebaseCheckbox`
+- `requireConfig`
+
+<!-- prettier-ignore -->
+!!! note
+    The above list is prepared manually and may become out of date.
+    Consult the self-hosted configuration docs and look for `inheritConfigSupport` values there for the definitive list.
+
+This way organizations can change/control the default behavior, like whether configs are required and how repositories are onboarded.
+
+We disabled `inheritConfig` in the Mend Renovate App to avoid wasting millions of API calls per week.
+This is because each `404` response from the GitHub API due to a missing org inherited config counts as a used API call.
+We will add a smart/dynamic approach in future, so that we can selectively enable `inheritConfig` per organization.
+
+## inheritConfigFileName
+
+Change this setting if you want Renovate to look for a different file name within the `inheritConfigRepoName` repository.
+You may use nested files, for example: `"some-dir/config.json"`.
+
+## inheritConfigRepoName
+
+Change this setting if you want Renovate to look in an alternative repository for the inherited config.
+The repository must be on the same platform and endpoint, and Renovate's token must have `read` permissions to the repository.
+
+## inheritConfigStrict
+
+By default Renovate will silently (debug log message only) ignore cases where `inheritConfig=true` but no inherited config is found.
+When you set `inheritConfigStrict=true` then Renovate will abort the run and raise a config error if Renovate can't find the inherited config.
+
+<!-- prettier-ignore -->
+!!! warning
+    Only set this config option to `true` if _every_ organization has an inherited config file _and_ you want to make sure Renovate _always_ uses that inherited config.
+
 ## logContext
 
 `logContext` is included with each log entry only if `logFormat="json"` - it is not included in the pretty log output.
diff --git a/lib/config/index.spec.ts b/lib/config/index.spec.ts
index 9a3e6a40c61fe9ebc7b531aab99bd3cdcb161bee..d8d81d4e2622131ffad4bd9f505af9a871651539 100644
--- a/lib/config/index.spec.ts
+++ b/lib/config/index.spec.ts
@@ -1,5 +1,10 @@
 import { getConfig } from './defaults';
-import { filterConfig, getManagerConfig, mergeChildConfig } from './index';
+import {
+  filterConfig,
+  getManagerConfig,
+  mergeChildConfig,
+  removeGlobalConfig,
+} from './index';
 
 jest.mock('../modules/datasource/npm');
 jest.mock('../../config.js', () => ({}), { virtual: true });
@@ -131,4 +136,20 @@ describe('config/index', () => {
       expect(config.vulnerabilitySeverity).toBe('CRITICAL');
     });
   });
+
+  describe('removeGlobalConfig()', () => {
+    it('removes all global config', () => {
+      const filteredConfig = removeGlobalConfig(defaultConfig, false);
+      expect(filteredConfig).not.toHaveProperty('onboarding');
+      expect(filteredConfig).not.toHaveProperty('binarySource');
+      expect(filteredConfig.prHourlyLimit).toBe(2);
+    });
+
+    it('retains inherited config', () => {
+      const filteredConfig = removeGlobalConfig(defaultConfig, true);
+      expect(filteredConfig).toHaveProperty('onboarding');
+      expect(filteredConfig).not.toHaveProperty('binarySource');
+      expect(filteredConfig.prHourlyLimit).toBe(2);
+    });
+  });
 });
diff --git a/lib/config/index.ts b/lib/config/index.ts
index 869a8250e5a9da907701d5e6496253b4f75e747e..0494348f4849a177ddaf119092f4c915c00981e6 100644
--- a/lib/config/index.ts
+++ b/lib/config/index.ts
@@ -31,6 +31,22 @@ export function getManagerConfig(
   return managerConfig;
 }
 
+export function removeGlobalConfig(
+  config: RenovateConfig,
+  keepInherited: boolean,
+): RenovateConfig {
+  const outputConfig: RenovateConfig = { ...config };
+  for (const option of options.getOptions()) {
+    if (keepInherited && option.inheritConfigSupport) {
+      continue;
+    }
+    if (option.globalOnly) {
+      delete outputConfig[option.name];
+    }
+  }
+  return outputConfig;
+}
+
 export function filterConfig(
   inputConfig: AllConfig,
   targetStage: RenovateConfigStage,
@@ -39,6 +55,7 @@ export function filterConfig(
   const outputConfig: RenovateConfig = { ...inputConfig };
   const stages: (string | undefined)[] = [
     'global',
+    'inherit',
     'repository',
     'package',
     'branch',
diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index fdaa18906471abe4be6a3f62362b0846952e6008..c8e743b6c16ec890b51a7741b9e55caf62f0b02f 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -122,6 +122,7 @@ const options: RenovateOptions[] = [
     type: 'string',
     default: 'renovate/configure',
     globalOnly: true,
+    inheritConfigSupport: true,
     cli: false,
   },
   {
@@ -131,6 +132,7 @@ const options: RenovateOptions[] = [
     type: 'string',
     default: null,
     globalOnly: true,
+    inheritConfigSupport: true,
     cli: false,
   },
   {
@@ -140,6 +142,7 @@ const options: RenovateOptions[] = [
     type: 'string',
     default: 'renovate.json',
     globalOnly: true,
+    inheritConfigSupport: true,
     cli: false,
   },
   {
@@ -148,6 +151,7 @@ const options: RenovateOptions[] = [
     type: 'boolean',
     default: false,
     globalOnly: true,
+    inheritConfigSupport: true,
   },
   {
     name: 'onboardingPrTitle',
@@ -156,6 +160,7 @@ const options: RenovateOptions[] = [
     type: 'string',
     default: 'Configure Renovate',
     globalOnly: true,
+    inheritConfigSupport: true,
     cli: false,
   },
   {
@@ -507,6 +512,7 @@ const options: RenovateOptions[] = [
     stage: 'repository',
     type: 'boolean',
     globalOnly: true,
+    inheritConfigSupport: true,
   },
   {
     name: 'onboardingConfig',
@@ -515,6 +521,7 @@ const options: RenovateOptions[] = [
     type: 'object',
     default: { $schema: 'https://docs.renovatebot.com/renovate-schema.json' },
     globalOnly: true,
+    inheritConfigSupport: true,
     mergeable: true,
   },
   {
@@ -583,6 +590,38 @@ const options: RenovateOptions[] = [
     default: true,
     globalOnly: true,
   },
+  {
+    name: 'inheritConfig',
+    description:
+      'If `true`, Renovate will inherit configuration from the `inheritConfigFileName` file in `inheritConfigRepoName',
+    type: 'boolean',
+    default: false,
+    globalOnly: true,
+  },
+  {
+    name: 'inheritConfigRepoName',
+    description:
+      'Renovate will look in this repo for the `inheritConfigFileName`.',
+    type: 'string',
+    default: '{{parentOrg}}/renovate-config',
+    globalOnly: true,
+  },
+  {
+    name: 'inheritConfigFileName',
+    description:
+      'Renovate will look for this config file name in the `inheritConfigRepoName`.',
+    type: 'string',
+    default: 'org-inherited-config.json',
+    globalOnly: true,
+  },
+  {
+    name: 'inheritConfigStrict',
+    description:
+      'If `true`, any `inheritedConfig` fetch errror will result in an aborted run.',
+    type: 'boolean',
+    default: false,
+    globalOnly: true,
+  },
   {
     name: 'requireConfig',
     description:
@@ -592,6 +631,7 @@ const options: RenovateOptions[] = [
     default: 'required',
     allowedValues: ['required', 'optional', 'ignored'],
     globalOnly: true,
+    inheritConfigSupport: true,
   },
   {
     name: 'optimizeForDisabled',
@@ -1921,6 +1961,7 @@ const options: RenovateOptions[] = [
     default: false,
     supportedPlatforms: ['bitbucket'],
     globalOnly: true,
+    inheritConfigSupport: true,
   },
   // Automatic merging
   {
diff --git a/lib/config/types.ts b/lib/config/types.ts
index 06ea517e8410e1361b57678c8a2d7ff9df1f9d8b..6200580499410068625bb0f0ab6652e3b20dc2fc 100644
--- a/lib/config/types.ts
+++ b/lib/config/types.ts
@@ -8,6 +8,7 @@ import type { MergeConfidence } from '../util/merge-confidence/types';
 
 export type RenovateConfigStage =
   | 'global'
+  | 'inherit'
   | 'repository'
   | 'package'
   | 'branch'
@@ -232,6 +233,11 @@ export interface RenovateConfig
 
   hostRules?: HostRule[];
 
+  inheritConfig?: boolean;
+  inheritConfigFileName?: string;
+  inheritConfigRepoName?: string;
+  inheritConfigStrict?: boolean;
+
   ignorePresets?: string[];
   forkProcessing?: 'auto' | 'enabled' | 'disabled';
   isFork?: boolean;
@@ -394,6 +400,8 @@ export interface RenovateOptionBase {
    */
   globalOnly?: boolean;
 
+  inheritConfigSupport?: boolean;
+
   allowedValues?: string[];
 
   allowString?: boolean;
diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts
index 9d675b5b7c578e854ef7810e2ba45828d55a5f42..1f0fc7290a7a868aa38540ec054fec8e3e4b8893 100644
--- a/lib/config/validation.spec.ts
+++ b/lib/config/validation.spec.ts
@@ -45,10 +45,30 @@ describe('config/validation', () => {
       expect(warnings).toHaveLength(2);
       expect(warnings).toMatchObject([
         {
-          message: `The "binarySource" option is a global option reserved only for Renovate's global configuration and cannot be configured within repository config file.`,
+          message: `The "binarySource" option is a global option reserved only for Renovate's global configuration and cannot be configured within a repository's config file.`,
         },
         {
-          message: `The "username" option is a global option reserved only for Renovate's global configuration and cannot be configured within repository config file.`,
+          message: `The "username" option is a global option reserved only for Renovate's global configuration and cannot be configured within a repository's config file.`,
+        },
+      ]);
+    });
+
+    it('catches global options in inherit config', async () => {
+      const config = {
+        binarySource: 'something',
+        username: 'user',
+      };
+      const { warnings } = await configValidation.validateConfig(
+        'inherit',
+        config,
+      );
+      expect(warnings).toHaveLength(2);
+      expect(warnings).toMatchObject([
+        {
+          message: `The "binarySource" option is a global option reserved only for Renovate's global configuration and cannot be configured within a repository's config file.`,
+        },
+        {
+          message: `The "username" option is a global option reserved only for Renovate's global configuration and cannot be configured within a repository's config file.`,
         },
       ]);
     });
@@ -70,6 +90,17 @@ describe('config/validation', () => {
       expect(warnings).toHaveLength(0);
     });
 
+    it('does not warn for valid inheritConfig', async () => {
+      const config = {
+        onboarding: false,
+      };
+      const { warnings } = await configValidation.validateConfig(
+        'inherit',
+        config,
+      );
+      expect(warnings).toHaveLength(0);
+    });
+
     it('catches invalid templates', async () => {
       const config = {
         commitMessage: '{{{something}}',
@@ -1020,7 +1051,7 @@ describe('config/validation', () => {
       expect(warnings).toMatchObject([
         {
           topic: 'Configuration Error',
-          message: `The "customEnvVariables" option is a global option reserved only for Renovate's global configuration and cannot be configured within repository config file.`,
+          message: `The "customEnvVariables" option is a global option reserved only for Renovate's global configuration and cannot be configured within a repository's config file.`,
         },
       ]);
     });
@@ -1426,7 +1457,7 @@ describe('config/validation', () => {
           },
           {
             topic: 'Configuration Error',
-            message: `The "binarySource" option is a global option reserved only for Renovate's global configuration and cannot be configured within repository config file.`,
+            message: `The "binarySource" option is a global option reserved only for Renovate's global configuration and cannot be configured within a repository's config file.`,
           },
         ]);
       });
diff --git a/lib/config/validation.ts b/lib/config/validation.ts
index 17c67b56928aedfbc489e3dedf810508e397be15..976a91b028644b2967523f7731c3cadcd4c3f7bc 100644
--- a/lib/config/validation.ts
+++ b/lib/config/validation.ts
@@ -40,6 +40,7 @@ const options = getOptions();
 let optionTypes: Record<string, RenovateOptions['type']>;
 let optionParents: Record<string, AllowedParents[]>;
 let optionGlobals: Set<string>;
+let optionInherits: Set<string>;
 
 const managerList = getManagerList();
 
@@ -98,6 +99,18 @@ function getDeprecationMessage(option: string): string | undefined {
   return deprecatedOptions[option];
 }
 
+function isInhertConfigOption(key: string): boolean {
+  if (!optionInherits) {
+    optionInherits = new Set();
+    for (const option of options) {
+      if (option.inheritConfigSupport) {
+        optionInherits.add(option.name);
+      }
+    }
+  }
+  return optionInherits.has(key);
+}
+
 function isGlobalOption(key: string): boolean {
   if (!optionGlobals) {
     optionGlobals = new Set();
@@ -121,7 +134,7 @@ export function getParentName(parentPath: string | undefined): string {
 }
 
 export async function validateConfig(
-  configType: 'global' | 'repo',
+  configType: 'global' | 'inherit' | 'repo',
   config: RenovateConfig,
   isPreset?: boolean,
   parentPath?: string,
@@ -164,22 +177,25 @@ export async function validateConfig(
       });
     }
 
-    if (configType === 'global' && isGlobalOption(key)) {
-      await validateGlobalConfig(
-        key,
-        val,
-        optionTypes[key],
-        warnings,
-        errors,
-        currentPath,
-        config,
-      );
-      continue;
-    } else {
-      if (isGlobalOption(key) && !isFalseGlobal(key, parentPath)) {
+    if (isGlobalOption(key)) {
+      if (configType === 'global') {
+        await validateGlobalConfig(
+          key,
+          val,
+          optionTypes[key],
+          warnings,
+          errors,
+          currentPath,
+          config,
+        );
+        continue;
+      } else if (
+        !isFalseGlobal(key, parentPath) &&
+        !(configType === 'inherit' && isInhertConfigOption(key))
+      ) {
         warnings.push({
           topic: 'Configuration Error',
-          message: `The "${key}" option is a global option reserved only for Renovate's global configuration and cannot be configured within repository config file.`,
+          message: `The "${key}" option is a global option reserved only for Renovate's global configuration and cannot be configured within a repository's config file.`,
         });
         continue;
       }
diff --git a/lib/constants/error-messages.ts b/lib/constants/error-messages.ts
index aa7da4b79e500e6c5e83752496f31d3b0e103cc7..434c39926f9d10ab85d2562b2975ba0a49badb22 100644
--- a/lib/constants/error-messages.ts
+++ b/lib/constants/error-messages.ts
@@ -17,6 +17,8 @@ export const CONFIG_PRESETS_INVALID = 'config-presets-invalid';
 export const CONFIG_SECRETS_EXPOSED = 'config-secrets-exposed';
 export const CONFIG_SECRETS_INVALID = 'config-secrets-invalid';
 export const CONFIG_GIT_URL_UNAVAILABLE = 'config-git-url-unavailable';
+export const CONFIG_INHERIT_NOT_FOUND = 'config-inherit-not-found';
+export const CONFIG_INHERIT_PARSE_ERROR = 'config-inherit-parse-error';
 
 // Repository Errors - causes repo to be considered as disabled
 export const REPOSITORY_ACCESS_FORBIDDEN = 'forbidden';
diff --git a/lib/workers/repository/init/config.ts b/lib/workers/repository/init/config.ts
index 96f64a7ba73913a486306bae18ab9492b3e82f57..a8f9a14c6dfeceb8b5b3293cdccd72dce10ab32b 100644
--- a/lib/workers/repository/init/config.ts
+++ b/lib/workers/repository/init/config.ts
@@ -1,5 +1,6 @@
 import type { RenovateConfig } from '../../../config/types';
 import { checkOnboardingBranch } from '../onboarding/branch';
+import { mergeInheritedConfig } from './inherited';
 import { mergeRenovateConfig } from './merge';
 
 // istanbul ignore next
@@ -8,6 +9,7 @@ export async function getRepoConfig(
 ): Promise<RenovateConfig> {
   let config = { ...config_ };
   config.baseBranch = config.defaultBranch;
+  config = await mergeInheritedConfig(config);
   config = await checkOnboardingBranch(config);
   config = await mergeRenovateConfig(config);
   return config;
diff --git a/lib/workers/repository/init/inherited.spec.ts b/lib/workers/repository/init/inherited.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f89c18201649c8397af7995baba786f1e6dc8ff8
--- /dev/null
+++ b/lib/workers/repository/init/inherited.spec.ts
@@ -0,0 +1,87 @@
+import { platform } from '../../../../test/util';
+import type { RenovateConfig } from '../../../config/types';
+import {
+  CONFIG_INHERIT_NOT_FOUND,
+  CONFIG_INHERIT_PARSE_ERROR,
+  CONFIG_VALIDATION,
+} from '../../../constants/error-messages';
+import { logger } from '../../../logger';
+import { mergeInheritedConfig } from './inherited';
+
+describe('workers/repository/init/inherited', () => {
+  let config: RenovateConfig;
+
+  beforeEach(() => {
+    config = {
+      repository: 'test/repo',
+      inheritConfig: true,
+      inheritConfigRepoName: 'inherit/repo',
+      inheritConfigFileName: 'config.json',
+      inheritConfigStrict: false,
+    };
+  });
+
+  it('should return the same config if repository or inheritConfig is not defined', async () => {
+    config.repository = undefined;
+    const result = await mergeInheritedConfig(config);
+    expect(result).toEqual(config);
+  });
+
+  it('should return the same config if inheritConfigRepoName or inheritConfigFileName is not a string', async () => {
+    config.inheritConfigRepoName = undefined;
+    const result = await mergeInheritedConfig(config);
+    expect(result).toEqual(config);
+  });
+
+  it('should throw an error if getting the raw file fails and inheritConfigStrict is true', async () => {
+    config.inheritConfigStrict = true;
+    platform.getRawFile.mockRejectedValue(new Error('File not found'));
+    await expect(mergeInheritedConfig(config)).rejects.toThrow(
+      CONFIG_INHERIT_NOT_FOUND,
+    );
+  });
+
+  it('should return the same config if getting the raw file fails and inheritConfigStrict is false', async () => {
+    platform.getRawFile.mockRejectedValue(new Error('File not found'));
+    const result = await mergeInheritedConfig(config);
+    expect(result).toEqual(config);
+  });
+
+  it('should throw an error if parsing the inherited config fails', async () => {
+    platform.getRawFile.mockResolvedValue('invalid json');
+    await expect(mergeInheritedConfig(config)).rejects.toThrow(
+      CONFIG_INHERIT_PARSE_ERROR,
+    );
+  });
+
+  it('should throw an error if config includes an invalid option', async () => {
+    platform.getRawFile.mockResolvedValue('{"something": "invalid"}');
+    await expect(mergeInheritedConfig(config)).rejects.toThrow(
+      CONFIG_VALIDATION,
+    );
+  });
+
+  it('should throw an error if config includes an invalid value', async () => {
+    platform.getRawFile.mockResolvedValue('{"onboarding": "invalid"}');
+    await expect(mergeInheritedConfig(config)).rejects.toThrow(
+      CONFIG_VALIDATION,
+    );
+  });
+
+  it('should warn if validateConfig returns warnings', async () => {
+    platform.getRawFile.mockResolvedValue('{"binarySource": "docker"}');
+    const res = await mergeInheritedConfig(config);
+    expect(res.binarySource).toBeUndefined();
+    expect(logger.warn).toHaveBeenCalled();
+  });
+
+  it('should merge inherited config', async () => {
+    platform.getRawFile.mockResolvedValue(
+      '{"onboarding":false,"labels":["test"]}',
+    );
+    const res = await mergeInheritedConfig(config);
+    expect(res.labels).toEqual(['test']);
+    expect(res.onboarding).toBeFalse();
+    expect(logger.warn).not.toHaveBeenCalled();
+  });
+});
diff --git a/lib/workers/repository/init/inherited.ts b/lib/workers/repository/init/inherited.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f25be4f3f3169e861084cb76d5faefab19cfcd9d
--- /dev/null
+++ b/lib/workers/repository/init/inherited.ts
@@ -0,0 +1,103 @@
+import is from '@sindresorhus/is';
+import { dequal } from 'dequal';
+import { mergeChildConfig, removeGlobalConfig } from '../../../config';
+import { parseFileConfig } from '../../../config/parse';
+import type { RenovateConfig } from '../../../config/types';
+import { validateConfig } from '../../../config/validation';
+import {
+  CONFIG_INHERIT_NOT_FOUND,
+  CONFIG_INHERIT_PARSE_ERROR,
+  CONFIG_VALIDATION,
+} from '../../../constants/error-messages';
+import { logger } from '../../../logger';
+import { platform } from '../../../modules/platform';
+import * as template from '../../../util/template';
+
+export async function mergeInheritedConfig(
+  config: RenovateConfig,
+): Promise<RenovateConfig> {
+  // typescript doesn't know that repo is defined
+  if (!config.repository || !config.inheritConfig) {
+    return config;
+  }
+  if (
+    !is.string(config.inheritConfigRepoName) ||
+    !is.string(config.inheritConfigFileName)
+  ) {
+    // Config validation should prevent this error
+    logger.error(
+      {
+        inheritConfigRepoName: config.inheritConfigRepoName,
+        inheritConfigFileName: config.inheritConfigFileName,
+      },
+      'Invalid inherited config.',
+    );
+    return config;
+  }
+  const templateConfig = {
+    topLevelOrg: config.topLevelOrg,
+    parentOrg: config.parentOrg,
+    repository: config.repository,
+  };
+  const inheritConfigRepoName = template.compile(
+    config.inheritConfigRepoName,
+    templateConfig,
+    false,
+  );
+  logger.trace(
+    { templateConfig, inheritConfigRepoName },
+    'Compiled inheritConfigRepoName result.',
+  );
+  logger.debug(
+    `Checking for inherited config file ${config.inheritConfigFileName} in repo ${inheritConfigRepoName}.`,
+  );
+  let configFileRaw: string | null = null;
+  try {
+    configFileRaw = await platform.getRawFile(
+      config.inheritConfigFileName,
+      inheritConfigRepoName,
+    );
+  } catch (err) {
+    if (config.inheritConfigStrict) {
+      logger.debug({ err }, 'Error getting inherited config.');
+      throw new Error(CONFIG_INHERIT_NOT_FOUND);
+    }
+    logger.trace({ err }, `Error getting inherited config.`);
+  }
+  if (!configFileRaw) {
+    logger.debug(`No inherited config found in ${inheritConfigRepoName}.`);
+    return config;
+  }
+  const parseResult = parseFileConfig(
+    config.inheritConfigFileName,
+    configFileRaw,
+  );
+  if (!parseResult.success) {
+    logger.debug({ parseResult }, 'Error parsing inherited config.');
+    throw new Error(CONFIG_INHERIT_PARSE_ERROR);
+  }
+  const inheritedConfig = parseResult.parsedContents as RenovateConfig;
+  logger.debug({ config: inheritedConfig }, `Inherited config`);
+  const res = await validateConfig('inherit', inheritedConfig);
+  if (res.errors.length) {
+    logger.warn(
+      { errors: res.errors },
+      'Found errors in inherited configuration.',
+    );
+    throw new Error(CONFIG_VALIDATION);
+  }
+  if (res.warnings.length) {
+    logger.warn(
+      { warnings: res.warnings },
+      'Found warnings in inherited configuration.',
+    );
+  }
+  const filteredConfig = removeGlobalConfig(inheritedConfig, true);
+  if (!dequal(inheritedConfig, filteredConfig)) {
+    logger.debug(
+      { inheritedConfig, filteredConfig },
+      'Removed global config from inherited config.',
+    );
+  }
+  return mergeChildConfig(config, filteredConfig);
+}