From 00b11a6c854e98e763b26fbc411eeb03ea7170c8 Mon Sep 17 00:00:00 2001 From: Gaston Yelmini Date: Thu, 28 May 2026 20:04:15 -0300 Subject: [PATCH] feat(runtime): always expose caCertificate and disableTlsVerification from env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These two fields back the platform-wide "agent configurations" feature (IntegrationPlatformFeatures.supportsAgentConfigurations) and are set by the customer through the global UI form, not declared per-integration. loadConfigFromEnvironmentVariables previously only iterated entries in the integration's instanceConfigFields, so any integration that did not re-declare these fields received undefined for both at runtime — even though the platform had written CA_CERTIFICATE / DISABLE_TLS_VERIFICATION into the environment. Merge them in as implicit optional fields. Integration-declared entries for the same keys still win, and createIntegrationInstanceForLocalExecution now always runs the loader (with an empty map if no instanceConfigFields were supplied) so the implicit fields surface even for integrations that do not declare a config schema of their own. --- .../src/execution/__tests__/config.test.ts | 47 +++++++++++++++++++ .../src/execution/config.ts | 24 +++++++++- .../src/execution/instance.ts | 10 ++-- 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/packages/integration-sdk-runtime/src/execution/__tests__/config.test.ts b/packages/integration-sdk-runtime/src/execution/__tests__/config.test.ts index 03f0e14f7..ce914ca75 100644 --- a/packages/integration-sdk-runtime/src/execution/__tests__/config.test.ts +++ b/packages/integration-sdk-runtime/src/execution/__tests__/config.test.ts @@ -20,6 +20,8 @@ afterEach(() => { delete process.env.STRING_VARIABLE; delete process.env.BOOLEAN_VARIABLE; delete process.env.STRING_ARRAY_VARIABLE; + delete process.env.CA_CERTIFICATE; + delete process.env.DISABLE_TLS_VERIFICATION; vol.reset(); }); @@ -108,6 +110,51 @@ test('throws error if expected environment boolean field does not match "true" o ); }); +test('loads CA_CERTIFICATE and DISABLE_TLS_VERIFICATION even when not declared in instanceConfigFields', () => { + process.env.CA_CERTIFICATE = + '-----BEGIN CERTIFICATE-----\nMIIB\n-----END CERTIFICATE-----'; + process.env.DISABLE_TLS_VERIFICATION = 'true'; + + const config = loadConfigFromEnvironmentVariables({}); + + expect(config).toEqual({ + caCertificate: + '-----BEGIN CERTIFICATE-----\nMIIB\n-----END CERTIFICATE-----', + disableTlsVerification: true, + }); +}); + +test('treats CA_CERTIFICATE and DISABLE_TLS_VERIFICATION as optional when env is not set', () => { + const instanceConfigFields: IntegrationInstanceConfigFieldMap< + Record<'stringVariable', IntegrationInstanceConfigField> + > = { + stringVariable: { + type: 'string', + }, + }; + + const config = loadConfigFromEnvironmentVariables(instanceConfigFields); + + expect(config).toEqual({ + stringVariable: 'string', + }); +}); + +test('respects integration-declared caCertificate / disableTlsVerification over implicit defaults', () => { + process.env.CA_CERTIFICATE = 'cert-value'; + const instanceConfigFields: IntegrationInstanceConfigFieldMap< + Record<'caCertificate', IntegrationInstanceConfigField> + > = { + caCertificate: { + type: 'string', + }, + }; + + const config = loadConfigFromEnvironmentVariables(instanceConfigFields); + + expect(config).toEqual({ caCertificate: 'cert-value' }); +}); + test('loads environment variables from .env', () => { vol.fromJSON({ [path.join(process.cwd(), '.env')]: 'MY_ENV_VAR=mochi', diff --git a/packages/integration-sdk-runtime/src/execution/config.ts b/packages/integration-sdk-runtime/src/execution/config.ts index 713a5171a..6636e16b7 100644 --- a/packages/integration-sdk-runtime/src/execution/config.ts +++ b/packages/integration-sdk-runtime/src/execution/config.ts @@ -11,6 +11,21 @@ import { const dotenvExpand = require('dotenv-expand'); +/** + * Global "agent configurations" that are exposed to every integration whose + * `integrationPlatformFeatures.supportsAgentConfigurations` is enabled. They + * are intentionally NOT required to be declared in `instanceConfigFields` so + * that integrations can opt in without per-integration schema changes. + * + * The values are consumed by `BaseAPIClient.getDefaultAgent()` in + * `@jupiterone/integration-sdk-http-client` and by the equivalent helper in + * `@private/http-client` inside the integrations monorepo. + */ +const IMPLICIT_AGENT_CONFIG_FIELDS: IntegrationInstanceConfigFieldMap = { + caCertificate: { type: 'string', optional: true }, + disableTlsVerification: { type: 'boolean', optional: true }, +}; + /** * Reads integration configuration from environment variables */ @@ -20,7 +35,14 @@ export function loadConfigFromEnvironmentVariables< // pull in environment variables from .env file if available dotenvExpand(dotenv.config()); - return Object.entries(configMap) + // Merge implicit agent-configuration fields without overriding any + // declarations the integration may have already made for the same key. + const mergedConfigMap = { + ...IMPLICIT_AGENT_CONFIG_FIELDS, + ...configMap, + } as IntegrationInstanceConfigFieldMap; + + return Object.entries(mergedConfigMap) .map(([field, config]): [string, string | object | boolean | undefined] => { const environmentVariableName = snakeCase(field).toUpperCase(); diff --git a/packages/integration-sdk-runtime/src/execution/instance.ts b/packages/integration-sdk-runtime/src/execution/instance.ts index 8818e4faf..4f94dd3da 100644 --- a/packages/integration-sdk-runtime/src/execution/instance.ts +++ b/packages/integration-sdk-runtime/src/execution/instance.ts @@ -52,9 +52,13 @@ export function createIntegrationInstanceForLocalExecution( process.env.INTEGRATION_INSTANCE_ACCOUNT_ID || process.env.JUPITERONE_LOCAL_INTEGRATION_INSTANCE_ACCOUNT_ID || LOCAL_INTEGRATION_INSTANCE.accountId, - config: config.instanceConfigFields - ? loadConfigFromEnvironmentVariables(config.instanceConfigFields) - : {}, + // Always call `loadConfigFromEnvironmentVariables` so that the implicit + // agent-configuration fields (caCertificate / disableTlsVerification) are + // picked up from the environment even when an integration does not declare + // any `instanceConfigFields` of its own. + config: loadConfigFromEnvironmentVariables( + config.instanceConfigFields ?? {}, + ), disabledSources: parseDisabledIngestionSourcesFromEnv(), }; }