diff --git a/config.schema.json b/config.schema.json index c72543037..7d132a1ab 100644 --- a/config.schema.json +++ b/config.schema.json @@ -367,6 +367,29 @@ } } } + }, + "upstreamProxy": { + "description": "Configuration for routing outbound requests to upstream Git hosts via an HTTP(S) proxy.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether to use an outbound HTTP(S) proxy for upstream Git hosts." + }, + "url": { + "type": "string", + "description": "Proxy URL used for outbound connections to upstream Git hosts when set.", + "format": "uri" + }, + "noProxy": { + "type": "array", + "description": "Additional hostnames or domain suffixes that should bypass the upstream proxy.", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false } }, "definitions": { diff --git a/package-lock.json b/package-lock.json index 394673bd2..ed244b13f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "express-session": "^1.19.0", "font-awesome": "^4.7.0", "history": "5.3.0", + "https-proxy-agent": "^7.0.6", "isomorphic-git": "^1.36.3", "jsonwebtoken": "^9.0.3", "load-plugin": "^6.0.3", @@ -5286,15 +5287,12 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", - "dependencies": { - "debug": "4" - }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/aggregate-error": { @@ -5683,6 +5681,31 @@ "proxy-from-env": "^2.1.0" } }, + "node_modules/axios/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/axios/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/backoff": { "version": "2.5.0", "license": "MIT", @@ -8907,16 +8930,16 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { diff --git a/package.json b/package.json index 35c20e11c..782d645df 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,7 @@ "express-session": "^1.19.0", "font-awesome": "^4.7.0", "history": "5.3.0", + "https-proxy-agent": "^7.0.6", "isomorphic-git": "^1.36.3", "jsonwebtoken": "^9.0.3", "load-plugin": "^6.0.3", diff --git a/proxy.config.json b/proxy.config.json index 715c38f48..f97332a69 100644 --- a/proxy.config.json +++ b/proxy.config.json @@ -156,6 +156,11 @@ } } ], + "upstreamProxy": { + "enabled": false, + "url": "http://localhost:8081", + "noProxy": [] + }, "tls": { "enabled": false, "key": "certs/key.pem", diff --git a/src/config/generated/config.ts b/src/config/generated/config.ts index 0a85e8e70..aa0c04e93 100644 --- a/src/config/generated/config.ts +++ b/src/config/generated/config.ts @@ -101,6 +101,10 @@ export interface GitProxyConfig { * UI routes that require authentication (logged in or admin) */ uiRouteAuth?: UIRouteAuth; + /** + * Configuration for routing outbound requests to upstream Git hosts via an HTTP(S) proxy. + */ + upstreamProxy?: UpstreamProxy; /** * Customisable URL shortener to share in proxy responses and warnings */ @@ -563,6 +567,24 @@ export interface RouteAuthRule { [property: string]: any; } +/** + * Configuration for routing outbound requests to upstream Git hosts via an HTTP(S) proxy. + */ +export interface UpstreamProxy { + /** + * Whether to use an outbound HTTP(S) proxy for upstream Git hosts. + */ + enabled?: boolean; + /** + * Additional hostnames or domain suffixes that should bypass the upstream proxy. + */ + noProxy?: string[]; + /** + * Proxy URL used for outbound connections to upstream Git hosts when set. + */ + url?: string; +} + // Converts JSON strings to/from your types // and asserts the results of JSON.parse at runtime export class Convert { @@ -780,6 +802,7 @@ const typeMap: any = { { json: 'tempPassword', js: 'tempPassword', typ: u(undefined, r('TempPassword')) }, { json: 'tls', js: 'tls', typ: u(undefined, r('TLS')) }, { json: 'uiRouteAuth', js: 'uiRouteAuth', typ: u(undefined, r('UIRouteAuth')) }, + { json: 'upstreamProxy', js: 'upstreamProxy', typ: u(undefined, r('UpstreamProxy')) }, { json: 'urlShortener', js: 'urlShortener', typ: u(undefined, '') }, ], false, @@ -981,6 +1004,14 @@ const typeMap: any = { ], 'any', ), + UpstreamProxy: o( + [ + { json: 'enabled', js: 'enabled', typ: u(undefined, true) }, + { json: 'noProxy', js: 'noProxy', typ: u(undefined, a('')) }, + { json: 'url', js: 'url', typ: u(undefined, '') }, + ], + false, + ), AuthenticationElementType: ['ActiveDirectory', 'jwt', 'local', 'openidconnect'], DatabaseType: ['fs', 'mongo'], }; diff --git a/src/config/index.ts b/src/config/index.ts index 0d4591300..0d0691271 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -149,6 +149,23 @@ export const getProxyUrl = (): string | undefined => { return config.proxyUrl; }; +/** + * Redacts the userinfo (credentials) from a proxy URL for safe logging. + * e.g. http://user:pass@proxy.corp.local:8080 → http://@proxy.corp.local:8080 + * + * WARNING: proxyUrl may contain plaintext credentials in the userinfo portion. + * Never log a raw proxy URL — always pass it through this helper first. + */ +export const redactProxyUrl = (url: string): string => { + return url.replace(/^(https?:\/\/)[^@]+@/, '$1@'); +}; + +// Get upstream proxy configuration +export const getUpstreamProxyConfig = () => { + const config = loadFullConfiguration(); + return config.upstreamProxy || {}; +}; + // Gets a list of authorised repositories export const getAuthorisedList = () => { const config = loadFullConfiguration(); diff --git a/src/proxy/routes/index.ts b/src/proxy/routes/index.ts index 6c809eff4..1a5014d2d 100644 --- a/src/proxy/routes/index.ts +++ b/src/proxy/routes/index.ts @@ -23,6 +23,9 @@ import { processUrlPath, validGitRequest } from './helper'; import { getAllProxiedHosts } from '../../db'; import { ProxyOptions } from 'express-http-proxy'; import { handleErrorAndLog } from '../../utils/errors'; +import { getUpstreamProxyConfig } from '../../config'; +import { HttpsProxyAgent } from 'https-proxy-agent'; +import { OutgoingHttpHeaders, RequestOptions } from 'http'; enum ActionType { ALLOWED = 'Allowed', @@ -144,7 +147,123 @@ const getRequestPathResolver: (prefix: string) => ProxyOptions['proxyReqPathReso }; }; -const proxyReqOptDecorator: ProxyOptions['proxyReqOptDecorator'] = (proxyReqOpts) => proxyReqOpts; +const getEnvProxyUrl = () => + process.env.HTTPS_PROXY || + process.env.https_proxy || + process.env.HTTP_PROXY || + process.env.http_proxy; + +const getEnvNoProxyList = (): string[] => { + const noProxy = process.env.NO_PROXY || process.env.no_proxy; + if (!noProxy) { + return []; + } + return noProxy + .split(',') + .map((entry) => entry.trim()) + .filter((entry) => entry.length > 0); +}; + +const hostMatchesNoProxy = (host: string | null | undefined, noProxyList: string[]): boolean => { + if (!host) { + return false; + } + + const hostname = host.split(':')[0]; + + return noProxyList.some((pattern) => { + if (!pattern) { + return false; + } + + const trimmed = pattern.trim().replace(/^\./, ''); // strip leading dot + if (trimmed === '*') return true; // wildcard - bypass all + + if (trimmed === '') { + return false; + } + + // Exact match + if (hostname === trimmed) { + return true; + } + + // Domain suffix match, e.g. example.com matches foo.example.com + if (hostname.endsWith(`.${trimmed}`)) { + return true; + } + + return false; + }); +}; + +// WARNING: proxyUrl may contain plaintext credentials in the userinfo portion +// (e.g. http://user:pass@proxy.corp.local:8080). Never log it directly — use +// redactProxyUrl() from config for any log statements involving this value. +let _cachedProxyAgent: { proxyUrl: string; agent: HttpsProxyAgent } | null = null; + +const getOrCreateProxyAgent = (proxyUrl: string): HttpsProxyAgent => { + if (!_cachedProxyAgent || _cachedProxyAgent.proxyUrl !== proxyUrl) { + let parsed: URL; + try { + parsed = new URL(proxyUrl); + } catch { + throw new Error( + `Invalid upstream proxy URL: check your upstreamProxy.url config or HTTPS_PROXY env var`, + ); + } + if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') { + throw new Error( + `Unsupported upstream proxy URL scheme "${parsed.protocol.replace(/:$/, '')}": only http and https are supported`, + ); + } + if (!parsed.hostname) { + throw new Error( + `Invalid upstream proxy URL: hostname is missing — check your upstreamProxy.url config or HTTPS_PROXY env var`, + ); + } + _cachedProxyAgent = { proxyUrl, agent: new HttpsProxyAgent(proxyUrl) }; + } + return _cachedProxyAgent.agent; +}; + +const buildUpstreamProxyAgent = ( + proxyReqOpts: Omit & { + headers: OutgoingHttpHeaders; + }, +) => { + const { enabled, url, noProxy } = getUpstreamProxyConfig(); + + const proxyUrl = url || getEnvProxyUrl(); + + // If enabled is not existant or false + if (enabled === undefined || enabled === false || !proxyUrl) { + return undefined; + } + + const host: string | null | undefined = proxyReqOpts.host || proxyReqOpts.hostname; + + const combinedNoProxy = [...(noProxy || []), ...getEnvNoProxyList()]; + + if (hostMatchesNoProxy(host, combinedNoProxy)) { + return undefined; + } + + return getOrCreateProxyAgent(proxyUrl); +}; + +const proxyReqOptDecorator: ProxyOptions['proxyReqOptDecorator'] = (proxyReqOpts, _srcReq) => { + const agent = buildUpstreamProxyAgent(proxyReqOpts); + + if (!agent) { + return proxyReqOpts; + } + + return { + ...proxyReqOpts, + agent, + }; +}; const proxyReqBodyDecorator: ProxyOptions['proxyReqBodyDecorator'] = (bodyContent, srcReq) => { if (srcReq.method === 'GET') { @@ -273,4 +392,7 @@ export { isPackPost, extractRawBody, validGitRequest, + buildUpstreamProxyAgent, + hostMatchesNoProxy, + getOrCreateProxyAgent, }; diff --git a/test/hostMatchesNoProxy.test.ts b/test/hostMatchesNoProxy.test.ts new file mode 100644 index 000000000..29b0e6be6 --- /dev/null +++ b/test/hostMatchesNoProxy.test.ts @@ -0,0 +1,114 @@ +/** + * Copyright 2026 GitProxy Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, it, expect } from 'vitest'; +import { hostMatchesNoProxy } from '../src/proxy/routes'; + +describe('hostMatchesNoProxy', () => { + describe('null / undefined / empty host', () => { + it('returns false for null host', () => { + expect(hostMatchesNoProxy(null, ['example.com'])).toBe(false); + }); + + it('returns false for undefined host', () => { + expect(hostMatchesNoProxy(undefined, ['example.com'])).toBe(false); + }); + + it('returns false for empty string host', () => { + expect(hostMatchesNoProxy('', ['example.com'])).toBe(false); + }); + }); + + describe('empty noProxyList', () => { + it('returns false when list is empty', () => { + expect(hostMatchesNoProxy('github.com', [])).toBe(false); + }); + }); + + describe('exact match', () => { + it('matches host exactly', () => { + expect(hostMatchesNoProxy('github.com', ['github.com'])).toBe(true); + }); + + it('does not match a different host', () => { + expect(hostMatchesNoProxy('gitlab.com', ['github.com'])).toBe(false); + }); + + it('strips port before matching', () => { + expect(hostMatchesNoProxy('github.com:443', ['github.com'])).toBe(true); + }); + + it('does not match a subdomain as exact', () => { + expect(hostMatchesNoProxy('api.github.com', ['github.com'])).toBe(true); // suffix match applies + }); + }); + + describe('domain suffix match', () => { + it('matches subdomain when pattern is the parent domain', () => { + expect(hostMatchesNoProxy('api.github.com', ['github.com'])).toBe(true); + }); + + it('matches deeply nested subdomain', () => { + expect(hostMatchesNoProxy('foo.bar.corp.local', ['corp.local'])).toBe(true); + }); + + it('does not match unrelated domain that happens to end with same string', () => { + expect(hostMatchesNoProxy('notgithub.com', ['github.com'])).toBe(false); + }); + }); + + describe('leading dot in pattern', () => { + it('strips leading dot and still matches subdomain', () => { + expect(hostMatchesNoProxy('api.github.com', ['.github.com'])).toBe(true); + }); + + it('strips leading dot and still matches exact host', () => { + expect(hostMatchesNoProxy('github.com', ['.github.com'])).toBe(true); + }); + }); + + describe('wildcard pattern', () => { + it('matches any host when pattern is *', () => { + expect(hostMatchesNoProxy('anything.example.com', ['*'])).toBe(true); + }); + + it('matches bare hostname when pattern is *', () => { + expect(hostMatchesNoProxy('localhost', ['*'])).toBe(true); + }); + }); + + describe('blank / whitespace patterns', () => { + it('ignores empty string pattern', () => { + expect(hostMatchesNoProxy('github.com', [''])).toBe(false); + }); + + it('ignores whitespace-only pattern', () => { + expect(hostMatchesNoProxy('github.com', [' '])).toBe(false); + }); + }); + + describe('multiple patterns', () => { + it('returns true when host matches any pattern in the list', () => { + expect(hostMatchesNoProxy('github.com', ['gitlab.com', 'github.com', 'bitbucket.org'])).toBe( + true, + ); + }); + + it('returns false when host matches none of the patterns', () => { + expect(hostMatchesNoProxy('github.com', ['gitlab.com', 'bitbucket.org'])).toBe(false); + }); + }); +}); diff --git a/test/redactProxyUrl.test.ts b/test/redactProxyUrl.test.ts new file mode 100644 index 000000000..16ce5cdc4 --- /dev/null +++ b/test/redactProxyUrl.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright 2026 GitProxy Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, it, expect } from 'vitest'; +import { redactProxyUrl } from '../src/config'; + +describe('redactProxyUrl', () => { + describe('URLs with credentials', () => { + it('redacts user and password from http URL', () => { + expect(redactProxyUrl('http://user:pass@proxy.corp.local:8080')).toBe( + 'http://@proxy.corp.local:8080', + ); + }); + + it('redacts user and password from https URL', () => { + expect(redactProxyUrl('https://user:pass@proxy.corp.local:8080')).toBe( + 'https://@proxy.corp.local:8080', + ); + }); + + it('redacts username-only (no password) from URL', () => { + expect(redactProxyUrl('http://user@proxy.corp.local:8080')).toBe( + 'http://@proxy.corp.local:8080', + ); + }); + + it('redacts credentials when no port is present', () => { + expect(redactProxyUrl('http://user:pass@proxy.corp.local')).toBe( + 'http://@proxy.corp.local', + ); + }); + + it('redacts credentials containing special characters', () => { + expect(redactProxyUrl('http://user:p%40ssw0rd!@proxy.corp.local:3128')).toBe( + 'http://@proxy.corp.local:3128', + ); + }); + }); + + describe('URLs without credentials', () => { + it('leaves http URL without credentials unchanged', () => { + expect(redactProxyUrl('http://proxy.corp.local:8080')).toBe('http://proxy.corp.local:8080'); + }); + + it('leaves https URL without credentials unchanged', () => { + expect(redactProxyUrl('https://proxy.corp.local:8080')).toBe('https://proxy.corp.local:8080'); + }); + }); +}); diff --git a/test/upstreamProxy.test.ts b/test/upstreamProxy.test.ts new file mode 100644 index 000000000..c80f03f14 --- /dev/null +++ b/test/upstreamProxy.test.ts @@ -0,0 +1,144 @@ +/** + * Copyright 2026 GitProxy Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; + +import { buildUpstreamProxyAgent, getOrCreateProxyAgent } from '../src/proxy/routes'; +import * as config from '../src/config'; + +vi.mock('../src/config', async (importOriginal) => { + const actual: any = await importOriginal(); + return { + ...actual, + getUpstreamProxyConfig: vi.fn(), + }; +}); + +describe('getOrCreateProxyAgent', () => { + it('accepts http:// URLs', () => { + expect(() => getOrCreateProxyAgent('http://proxy.example.com:8080')).not.toThrow(); + }); + + it('accepts https:// URLs', () => { + expect(() => getOrCreateProxyAgent('https://proxy.example.com:8080')).not.toThrow(); + }); + + it('rejects socks5:// URLs with a descriptive error', () => { + expect(() => getOrCreateProxyAgent('socks5://proxy.example.com:1080')).toThrow( + /unsupported.*scheme.*socks5/i, + ); + }); + + it('rejects ftp:// URLs with a descriptive error', () => { + expect(() => getOrCreateProxyAgent('ftp://proxy.example.com:21')).toThrow( + /unsupported.*scheme.*ftp/i, + ); + }); + + it('rejects URLs without a protocol (no scheme)', () => { + expect(() => getOrCreateProxyAgent('localhost:8081')).toThrow( + /Unsupported upstream proxy URL scheme/i, + ); + }); + + it('rejects URLs with an empty hostname', () => { + expect(() => getOrCreateProxyAgent('http://:8080')).toThrow(/invalid upstream proxy url/i); + }); + + it('rejects completely invalid URL strings', () => { + expect(() => getOrCreateProxyAgent('not a url at all')).toThrow(/invalid upstream proxy url/i); + }); +}); + +describe('buildUpstreamProxyAgent', () => { + const originalEnv = process.env; + + beforeEach(() => { + vi.resetModules(); + process.env = { ...originalEnv }; + vi.mocked(config.getUpstreamProxyConfig).mockReturnValue({}); + }); + + afterEach(() => { + process.env = originalEnv; + }); + + it('returns undefined when no proxy configuration or environment variables are set', () => { + const agent = buildUpstreamProxyAgent({ host: 'github.com', headers: {} }); + expect(agent).toBeUndefined(); + }); + + it('uses upstreamProxy.url when enabled in configuration', () => { + vi.mocked(config.getUpstreamProxyConfig).mockReturnValue({ + enabled: true, + url: 'http://proxy.example.com:8080', + }); + + const agent = buildUpstreamProxyAgent({ host: 'github.com', headers: {} }); + expect(agent).toBeDefined(); + }); + + it('prefers configuration URL over environment variables', () => { + process.env.HTTPS_PROXY = 'http://env-proxy.example.com:8080'; + vi.mocked(config.getUpstreamProxyConfig).mockReturnValue({ + enabled: true, + url: 'http://config-proxy.example.com:8080', + }); + + const agent = buildUpstreamProxyAgent({ host: 'github.com', headers: {} }); + expect(agent).toBeDefined(); + expect(agent?.proxy.href).toBe('http://config-proxy.example.com:8080/'); + }); + + it('creates an agent when only HTTPS_PROXY is set and config is empty', () => { + process.env.HTTPS_PROXY = 'http://env-proxy.example.com:8080'; + vi.mocked(config.getUpstreamProxyConfig).mockReturnValue({ enabled: true }); + + const agent = buildUpstreamProxyAgent({ host: 'github.com', headers: {} }); + expect(agent).toBeDefined(); + expect(agent?.proxy.href).toBe('http://env-proxy.example.com:8080/'); + }); + + it('does not create an agent when upstreamProxy.enabled is false', () => { + process.env.HTTPS_PROXY = 'http://env-proxy.example.com:8080'; + vi.mocked(config.getUpstreamProxyConfig).mockReturnValue({ + enabled: false, + url: 'http://config-proxy.example.com:8080', + }); + + const agent = buildUpstreamProxyAgent({ host: 'github.com', headers: {} }); + expect(agent).toBeUndefined(); + }); + + it('bypasses proxy when host matches noProxy in configuration', () => { + vi.mocked(config.getUpstreamProxyConfig).mockReturnValue({ + enabled: true, + url: 'http://config-proxy.example.com:8080', + noProxy: ['github.com'], + }); + + const agent = buildUpstreamProxyAgent({ host: 'github.com', headers: {} }); + expect(agent).toBeUndefined(); + }); + + it('bypasses proxy when host matches NO_PROXY environment variable', () => { + process.env.HTTPS_PROXY = 'http://env-proxy.example.com:8080'; + process.env.NO_PROXY = 'github.com'; + + const agent = buildUpstreamProxyAgent({ host: 'github.com', headers: {} }); + expect(agent).toBeUndefined(); + }); +}); diff --git a/website/docs/architecture/architecture.md b/website/docs/architecture/architecture.md index e91a3d457..97da3ce38 100644 --- a/website/docs/architecture/architecture.md +++ b/website/docs/architecture/architecture.md @@ -222,6 +222,26 @@ Currently supports the following out-of-the-box: - ActiveDirectory auth configuration for querying via a REST API rather than LDAP - Gitleaks configuration +#### `upstreamProxy` + +Configures routing of outbound requests from the GitProxy server to upstream Git hosts (e.g. GitHub, GitLab) via an HTTP(S) proxy. Use this when the server runs in an environment where direct Internet access is not allowed and all traffic must go through a corporate web proxy ("proxying the proxy"). + +- **`enabled`** (boolean): When `true`, outbound connections to upstream Git hosts use the configured proxy. When `false`, the proxy is not used even if `url` or environment variables are set. +- **`url`** (string): The HTTP(S) proxy URL (e.g. `http://proxy.corp.local:8080` or `http://user:pass@proxy.corp.local:8080`). If omitted, GitProxy falls back to the `HTTPS_PROXY`, `https_proxy`, `HTTP_PROXY` or `http_proxy` environment variables (first defined wins). +- **`noProxy`** (array of strings, optional): Hostnames or domain suffixes for which the proxy should be bypassed (e.g. internal Git hosts). Combined with the `NO_PROXY` / `no_proxy` environment variable. + +Example: + +```json +"upstreamProxy": { + "enabled": true, + "url": "http://proxy.corp.local:8080", + "noProxy": ["github.corp.local", "gitlab.corp.local"] +} +``` + +If `upstreamProxy` is not configured, setting only `HTTPS_PROXY` (or `HTTP_PROXY`) in the environment will also enable use of that proxy for outbound connections, unless `enabled` is explicitly set to `false` in config. + #### `commitConfig` Used in [`checkCommitMessages`](processors.md#checkcommitmessages), [`checkAuthorEmails`](processors.md#checkauthoremails) and [`scanDiff`](processors.md#scandiff) processors to block pushes depending on the given rules. diff --git a/website/docs/configuration/reference.mdx b/website/docs/configuration/reference.mdx index 361415bbf..134d026d4 100644 --- a/website/docs/configuration/reference.mdx +++ b/website/docs/configuration/reference.mdx @@ -17,7 +17,8 @@ description: JSON schema reference documentation for GitProxy
- 1. [Optional] Property GitProxy configuration file > proxyUrl + 1. [Optional] Property GitProxy configuration file > proxyUrl +
@@ -33,7 +34,8 @@ description: JSON schema reference documentation for GitProxy
- 2. [Optional] Property GitProxy configuration file > cookieSecret + 2. [Optional] Property GitProxy configuration file > cookieSecret +
@@ -47,7 +49,8 @@ description: JSON schema reference documentation for GitProxy
- 3. [Optional] Property GitProxy configuration file > sessionMaxAgeHours + 3. [Optional] Property GitProxy configuration file > sessionMaxAgeHours +
@@ -61,7 +64,8 @@ description: JSON schema reference documentation for GitProxy
- 4. [Optional] Property GitProxy configuration file > api + 4. [Optional] Property GitProxy configuration file > api +
@@ -75,7 +79,8 @@ description: JSON schema reference documentation for GitProxy
- 4.1. [Optional] Property GitProxy configuration file > api > ls + 4.1. [Optional] Property GitProxy configuration file > api > ls +
@@ -89,7 +94,8 @@ description: JSON schema reference documentation for GitProxy
- 4.1.1. [Optional] Property GitProxy configuration file > api > ls > userInADGroup + 4.1.1. [Optional] Property GitProxy configuration file > api > ls > userInADGroup +
@@ -114,7 +120,8 @@ description: JSON schema reference documentation for GitProxy
- 4.2. [Optional] Property GitProxy configuration file > api > gitleaks + 4.2. [Optional] Property GitProxy configuration file > api > gitleaks +
@@ -128,7 +135,8 @@ description: JSON schema reference documentation for GitProxy
- 4.2.1. [Optional] Property GitProxy configuration file > api > gitleaks > enabled + 4.2.1. [Optional] Property GitProxy configuration file > api > gitleaks > enabled +
@@ -142,7 +150,8 @@ description: JSON schema reference documentation for GitProxy
- 4.2.2. [Optional] Property GitProxy configuration file > api > gitleaks > ignoreGitleaksAllow + 4.2.2. [Optional] Property GitProxy configuration file > api > gitleaks > ignoreGitleaksAllow +
@@ -156,7 +165,8 @@ description: JSON schema reference documentation for GitProxy
- 4.2.3. [Optional] Property GitProxy configuration file > api > gitleaks > noColor + 4.2.3. [Optional] Property GitProxy configuration file > api > gitleaks > noColor +
@@ -170,7 +180,8 @@ description: JSON schema reference documentation for GitProxy
- 4.2.4. [Optional] Property GitProxy configuration file > api > gitleaks > configPath + 4.2.4. [Optional] Property GitProxy configuration file > api > gitleaks > configPath +
@@ -190,7 +201,8 @@ description: JSON schema reference documentation for GitProxy
- 5. [Optional] Property GitProxy configuration file > commitConfig + 5. [Optional] Property GitProxy configuration file > commitConfig +
@@ -206,7 +218,8 @@ description: JSON schema reference documentation for GitProxy
- 5.1. [Optional] Property GitProxy configuration file > commitConfig > author + 5.1. [Optional] Property GitProxy configuration file > commitConfig > author +
@@ -222,7 +235,8 @@ description: JSON schema reference documentation for GitProxy
- 5.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email + 5.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email +
@@ -238,7 +252,8 @@ description: JSON schema reference documentation for GitProxy
- 5.1.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > local + 5.1.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > local +
@@ -254,7 +269,8 @@ description: JSON schema reference documentation for GitProxy
- 5.1.1.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > local > block + 5.1.1.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > local > block +
@@ -275,7 +291,8 @@ description: JSON schema reference documentation for GitProxy
- 5.1.1.2. [Optional] Property GitProxy configuration file > commitConfig > author > email > domain + 5.1.1.2. [Optional] Property GitProxy configuration file > commitConfig > author > email > domain +
@@ -291,7 +308,8 @@ description: JSON schema reference documentation for GitProxy
- 5.1.1.2.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > domain > allow + 5.1.1.2.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > domain > allow +
@@ -318,7 +336,8 @@ description: JSON schema reference documentation for GitProxy
- 5.2. [Optional] Property GitProxy configuration file > commitConfig > message + 5.2. [Optional] Property GitProxy configuration file > commitConfig > message +
@@ -334,7 +353,8 @@ description: JSON schema reference documentation for GitProxy
- 5.2.1. [Optional] Property GitProxy configuration file > commitConfig > message > block + 5.2.1. [Optional] Property GitProxy configuration file > commitConfig > message > block +
@@ -350,7 +370,8 @@ description: JSON schema reference documentation for GitProxy
- 5.2.1.1. [Optional] Property GitProxy configuration file > commitConfig > message > block > literals + 5.2.1.1. [Optional] Property GitProxy configuration file > commitConfig > message > block > literals +
@@ -379,7 +400,8 @@ description: JSON schema reference documentation for GitProxy
- 5.2.1.2. [Optional] Property GitProxy configuration file > commitConfig > message > block > patterns + 5.2.1.2. [Optional] Property GitProxy configuration file > commitConfig > message > block > patterns +
@@ -414,7 +436,8 @@ description: JSON schema reference documentation for GitProxy
- 5.3. [Optional] Property GitProxy configuration file > commitConfig > diff + 5.3. [Optional] Property GitProxy configuration file > commitConfig > diff +
@@ -430,7 +453,8 @@ description: JSON schema reference documentation for GitProxy
- 5.3.1. [Optional] Property GitProxy configuration file > commitConfig > diff > block + 5.3.1. [Optional] Property GitProxy configuration file > commitConfig > diff > block +
@@ -446,7 +470,8 @@ description: JSON schema reference documentation for GitProxy
- 5.3.1.1. [Optional] Property GitProxy configuration file > commitConfig > diff > block > literals + 5.3.1.1. [Optional] Property GitProxy configuration file > commitConfig > diff > block > literals +
@@ -475,7 +500,8 @@ description: JSON schema reference documentation for GitProxy
- 5.3.1.2. [Optional] Property GitProxy configuration file > commitConfig > diff > block > patterns + 5.3.1.2. [Optional] Property GitProxy configuration file > commitConfig > diff > block > patterns +
@@ -505,7 +531,8 @@ description: JSON schema reference documentation for GitProxy
- 5.3.1.3. [Optional] Property GitProxy configuration file > commitConfig > diff > block > providers + 5.3.1.3. [Optional] Property GitProxy configuration file > commitConfig > diff > block > providers +
@@ -521,7 +548,8 @@ description: JSON schema reference documentation for GitProxy
- 5.3.1.3.1. Property GitProxy configuration file > commitConfig > diff > block > providers > additionalProperties + 5.3.1.3.1. Property GitProxy configuration file > commitConfig > diff > block > providers > additionalProperties +
@@ -547,7 +575,8 @@ description: JSON schema reference documentation for GitProxy
- 6. [Optional] Property GitProxy configuration file > attestationConfig + 6. [Optional] Property GitProxy configuration file > attestationConfig +
@@ -563,7 +592,8 @@ description: JSON schema reference documentation for GitProxy
- 6.1. [Optional] Property GitProxy configuration file > attestationConfig > questions + 6.1. [Optional] Property GitProxy configuration file > attestationConfig > questions +
@@ -592,7 +622,8 @@ description: JSON schema reference documentation for GitProxy
- 6.1.1.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > label + 6.1.1.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > label +
@@ -610,7 +641,8 @@ description: JSON schema reference documentation for GitProxy
- 6.1.1.2. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip + 6.1.1.2. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip +
@@ -626,7 +658,8 @@ description: JSON schema reference documentation for GitProxy
- 6.1.1.2.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > text + 6.1.1.2.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > text +
@@ -642,7 +675,8 @@ description: JSON schema reference documentation for GitProxy
- 6.1.1.2.2. [Optional] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links + 6.1.1.2.2. [Optional] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links +
@@ -667,7 +701,8 @@ description: JSON schema reference documentation for GitProxy
- 6.1.1.2.2.1.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links > links items > text + 6.1.1.2.2.1.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links > links items > text +
@@ -683,7 +718,8 @@ description: JSON schema reference documentation for GitProxy
- 6.1.1.2.2.1.2. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links > links items > url + 6.1.1.2.2.1.2. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links > links items > url +
@@ -712,7 +748,8 @@ description: JSON schema reference documentation for GitProxy
- 7. [Optional] Property GitProxy configuration file > domains + 7. [Optional] Property GitProxy configuration file > domains +
@@ -726,7 +763,8 @@ description: JSON schema reference documentation for GitProxy
- 7.1. [Optional] Property GitProxy configuration file > domains > proxy + 7.1. [Optional] Property GitProxy configuration file > domains > proxy +
@@ -745,7 +783,8 @@ description: JSON schema reference documentation for GitProxy
- 7.2. [Optional] Property GitProxy configuration file > domains > service + 7.2. [Optional] Property GitProxy configuration file > domains > service +
@@ -767,7 +806,8 @@ description: JSON schema reference documentation for GitProxy
- 8. [Optional] Property GitProxy configuration file > rateLimit + 8. [Optional] Property GitProxy configuration file > rateLimit +
@@ -781,7 +821,8 @@ description: JSON schema reference documentation for GitProxy
- 8.1. [Required] Property GitProxy configuration file > rateLimit > windowMs + 8.1. [Required] Property GitProxy configuration file > rateLimit > windowMs +
@@ -797,7 +838,8 @@ description: JSON schema reference documentation for GitProxy
- 8.2. [Required] Property GitProxy configuration file > rateLimit > limit + 8.2. [Required] Property GitProxy configuration file > rateLimit > limit +
@@ -813,7 +855,8 @@ description: JSON schema reference documentation for GitProxy
- 8.3. [Optional] Property GitProxy configuration file > rateLimit > statusCode + 8.3. [Optional] Property GitProxy configuration file > rateLimit > statusCode +
@@ -829,7 +872,8 @@ description: JSON schema reference documentation for GitProxy
- 8.4. [Optional] Property GitProxy configuration file > rateLimit > message + 8.4. [Optional] Property GitProxy configuration file > rateLimit > message +
@@ -848,7 +892,8 @@ description: JSON schema reference documentation for GitProxy
- 9. [Optional] Property GitProxy configuration file > privateOrganizations + 9. [Optional] Property GitProxy configuration file > privateOrganizations +
@@ -864,7 +909,8 @@ description: JSON schema reference documentation for GitProxy
- 10. [Optional] Property GitProxy configuration file > urlShortener + 10. [Optional] Property GitProxy configuration file > urlShortener +
@@ -880,7 +926,8 @@ description: JSON schema reference documentation for GitProxy
- 11. [Optional] Property GitProxy configuration file > contactEmail + 11. [Optional] Property GitProxy configuration file > contactEmail +
@@ -896,7 +943,8 @@ description: JSON schema reference documentation for GitProxy
- 12. [Optional] Property GitProxy configuration file > csrfProtection + 12. [Optional] Property GitProxy configuration file > csrfProtection +
@@ -912,7 +960,8 @@ description: JSON schema reference documentation for GitProxy
- 13. [Optional] Property GitProxy configuration file > plugins + 13. [Optional] Property GitProxy configuration file > plugins +
@@ -939,7 +988,8 @@ description: JSON schema reference documentation for GitProxy
- 14. [Optional] Property GitProxy configuration file > authorisedList + 14. [Optional] Property GitProxy configuration file > authorisedList +
@@ -965,7 +1015,8 @@ description: JSON schema reference documentation for GitProxy
- 14.1.1. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > project + 14.1.1. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > project +
@@ -979,7 +1030,8 @@ description: JSON schema reference documentation for GitProxy
- 14.1.2. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > name + 14.1.2. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > name +
@@ -993,7 +1045,8 @@ description: JSON schema reference documentation for GitProxy
- 14.1.3. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > url + 14.1.3. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > url +
@@ -1010,7 +1063,8 @@ description: JSON schema reference documentation for GitProxy
- 15. [Optional] Property GitProxy configuration file > sink + 15. [Optional] Property GitProxy configuration file > sink +
@@ -1057,7 +1111,8 @@ description: JSON schema reference documentation for GitProxy
- 15.1.1.1. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > type + 15.1.1.1. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > type +
@@ -1073,7 +1128,8 @@ Specific value: `"mongo"`
- 15.1.1.2. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > enabled + 15.1.1.2. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > enabled +
@@ -1087,7 +1143,8 @@ Specific value: `"mongo"`
- 15.1.1.3. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > connectionString + 15.1.1.3. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > connectionString +
@@ -1103,7 +1160,8 @@ Specific value: `"mongo"`
- 15.1.1.4. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options + 15.1.1.4. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options +
@@ -1117,7 +1175,8 @@ Specific value: `"mongo"`
- 15.1.1.4.1. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options > authMechanismProperties + 15.1.1.4.1. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options > authMechanismProperties +
@@ -1129,7 +1188,8 @@ Specific value: `"mongo"`
- 15.1.1.4.1.1. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options > authMechanismProperties > AWS_CREDENTIAL_PROVIDER + 15.1.1.4.1.1. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options > authMechanismProperties > AWS_CREDENTIAL_PROVIDER +
@@ -1164,7 +1224,8 @@ Specific value: `"mongo"`
- 15.1.2.1. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 1 > type + 15.1.2.1. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 1 > type +
@@ -1180,7 +1241,8 @@ Specific value: `"fs"`
- 15.1.2.2. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 1 > enabled + 15.1.2.2. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 1 > enabled +
@@ -1201,7 +1263,8 @@ Specific value: `"fs"`
- 16. [Optional] Property GitProxy configuration file > authentication + 16. [Optional] Property GitProxy configuration file > authentication +
@@ -1252,7 +1315,8 @@ Specific value: `"fs"`
- 16.1.1.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config > type + 16.1.1.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config > type +
@@ -1268,7 +1332,8 @@ Specific value: `"local"`
- 16.1.1.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config > enabled + 16.1.1.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config > enabled +
@@ -1297,7 +1362,8 @@ Specific value: `"local"`
- 16.1.2.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > type + 16.1.2.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > type +
@@ -1313,7 +1379,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > enabled + 16.1.2.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > enabled +
@@ -1327,7 +1394,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adminGroup + 16.1.2.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adminGroup +
@@ -1343,7 +1411,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > userGroup + 16.1.2.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > userGroup +
@@ -1359,7 +1428,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.5. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > domain + 16.1.2.5. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > domain +
@@ -1375,7 +1445,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.6. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig + 16.1.2.6. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig +
@@ -1389,7 +1460,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.6.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > url + 16.1.2.6.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > url +
@@ -1405,7 +1477,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.6.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > baseDN + 16.1.2.6.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > baseDN +
@@ -1421,7 +1494,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.6.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > username + 16.1.2.6.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > username +
@@ -1437,7 +1511,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.6.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > password + 16.1.2.6.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > password +
@@ -1453,7 +1528,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.2.6.5. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > searchBase + 16.1.2.6.5. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > searchBase +
@@ -1487,7 +1563,8 @@ Specific value: `"ActiveDirectory"`
- 16.1.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > type + 16.1.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > type +
@@ -1503,7 +1580,8 @@ Specific value: `"openidconnect"`
- 16.1.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > enabled + 16.1.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > enabled +
@@ -1517,7 +1595,8 @@ Specific value: `"openidconnect"`
- 16.1.3.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig + 16.1.3.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig +
@@ -1531,7 +1610,8 @@ Specific value: `"openidconnect"`
- 16.1.3.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > issuer + 16.1.3.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > issuer +
@@ -1545,7 +1625,8 @@ Specific value: `"openidconnect"`
- 16.1.3.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > clientID + 16.1.3.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > clientID +
@@ -1559,7 +1640,8 @@ Specific value: `"openidconnect"`
- 16.1.3.3.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > clientSecret + 16.1.3.3.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > clientSecret +
@@ -1573,7 +1655,8 @@ Specific value: `"openidconnect"`
- 16.1.3.3.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > callbackURL + 16.1.3.3.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > callbackURL +
@@ -1587,7 +1670,8 @@ Specific value: `"openidconnect"`
- 16.1.3.3.5. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > scope + 16.1.3.3.5. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > scope +
@@ -1619,7 +1703,8 @@ Specific value: `"openidconnect"`
- 16.1.4.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > type + 16.1.4.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > type +
@@ -1635,7 +1720,8 @@ Specific value: `"jwt"`
- 16.1.4.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > enabled + 16.1.4.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > enabled +
@@ -1649,7 +1735,8 @@ Specific value: `"jwt"`
- 16.1.4.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig + 16.1.4.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig +
@@ -1663,7 +1750,8 @@ Specific value: `"jwt"`
- 16.1.4.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > clientID + 16.1.4.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > clientID +
@@ -1677,7 +1765,8 @@ Specific value: `"jwt"`
- 16.1.4.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > authorityURL + 16.1.4.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > authorityURL +
@@ -1691,7 +1780,8 @@ Specific value: `"jwt"`
- 16.1.4.3.3. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > expectedAudience + 16.1.4.3.3. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > expectedAudience +
@@ -1705,7 +1795,8 @@ Specific value: `"jwt"`
- 16.1.4.3.4. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > roleMapping + 16.1.4.3.4. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > roleMapping +
@@ -1717,7 +1808,8 @@ Specific value: `"jwt"`
- 16.1.4.3.4.1. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > roleMapping > admin + 16.1.4.3.4.1. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > roleMapping > admin +
@@ -1745,7 +1837,8 @@ Specific value: `"jwt"`
- 17. [Optional] Property GitProxy configuration file > tempPassword + 17. [Optional] Property GitProxy configuration file > tempPassword +
@@ -1759,7 +1852,8 @@ Specific value: `"jwt"`
- 17.1. [Optional] Property GitProxy configuration file > tempPassword > sendEmail + 17.1. [Optional] Property GitProxy configuration file > tempPassword > sendEmail +
@@ -1773,7 +1867,8 @@ Specific value: `"jwt"`
- 17.2. [Optional] Property GitProxy configuration file > tempPassword > emailConfig + 17.2. [Optional] Property GitProxy configuration file > tempPassword > emailConfig +
@@ -1793,7 +1888,8 @@ Specific value: `"jwt"`
- 18. [Optional] Property GitProxy configuration file > apiAuthentication + 18. [Optional] Property GitProxy configuration file > apiAuthentication +
@@ -1824,7 +1920,8 @@ Specific value: `"jwt"`
- 19. [Optional] Property GitProxy configuration file > tls + 19. [Optional] Property GitProxy configuration file > tls +
@@ -1838,7 +1935,8 @@ Specific value: `"jwt"`
- 19.1. [Required] Property GitProxy configuration file > tls > enabled + 19.1. [Required] Property GitProxy configuration file > tls > enabled +
@@ -1852,7 +1950,8 @@ Specific value: `"jwt"`
- 19.2. [Required] Property GitProxy configuration file > tls > key + 19.2. [Required] Property GitProxy configuration file > tls > key +
@@ -1866,7 +1965,8 @@ Specific value: `"jwt"`
- 19.3. [Required] Property GitProxy configuration file > tls > cert + 19.3. [Required] Property GitProxy configuration file > tls > cert +
@@ -1883,7 +1983,8 @@ Specific value: `"jwt"`
- 20. [Optional] Property GitProxy configuration file > sslKeyPemPath + 20. [Optional] Property GitProxy configuration file > sslKeyPemPath +
@@ -1899,7 +2000,8 @@ Specific value: `"jwt"`
- 21. [Optional] Property GitProxy configuration file > sslCertPemPath + 21. [Optional] Property GitProxy configuration file > sslCertPemPath +
@@ -1915,7 +2017,8 @@ Specific value: `"jwt"`
- 22. [Optional] Property GitProxy configuration file > configurationSources + 22. [Optional] Property GitProxy configuration file > configurationSources +
@@ -1930,7 +2033,8 @@ Specific value: `"jwt"`
- 23. [Optional] Property GitProxy configuration file > uiRouteAuth + 23. [Optional] Property GitProxy configuration file > uiRouteAuth +
@@ -1944,7 +2048,8 @@ Specific value: `"jwt"`
- 23.1. [Optional] Property GitProxy configuration file > uiRouteAuth > enabled + 23.1. [Optional] Property GitProxy configuration file > uiRouteAuth > enabled +
@@ -1958,7 +2063,8 @@ Specific value: `"jwt"`
- 23.2. [Optional] Property GitProxy configuration file > uiRouteAuth > rules + 23.2. [Optional] Property GitProxy configuration file > uiRouteAuth > rules +
@@ -1982,7 +2088,8 @@ Specific value: `"jwt"`
- 23.2.1.1. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > pattern + 23.2.1.1. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > pattern +
@@ -1996,7 +2103,23 @@ Specific value: `"jwt"`
- 23.2.1.2. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > adminOnly + 23.2.1.2. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > adminOnly + + +
+ +| | | +| ------------ | --------- | +| **Type** | `boolean` | +| **Required** | No | + +
+
+ +
+ + 23.2.1.3. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > loginRequired +
@@ -2008,9 +2131,31 @@ Specific value: `"jwt"`
+
+
+ +
+
+ +
+ + 24. [Optional] Property GitProxy configuration file > upstreamProxy + + +
+ +| | | +| ------------------------- | ----------- | +| **Type** | `object` | +| **Required** | No | +| **Additional properties** | Not allowed | + +**Description:** Configuration for routing outbound requests to upstream Git hosts via an HTTP(S) proxy. +
- 23.2.1.3. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > loginRequired + 24.1. [Optional] Property GitProxy configuration file > upstreamProxy > enabled +
@@ -2019,9 +2164,54 @@ Specific value: `"jwt"` | **Type** | `boolean` | | **Required** | No | +**Description:** Whether to use an outbound HTTP(S) proxy for upstream Git hosts. + +
+
+ +
+ + 24.2. [Optional] Property GitProxy configuration file > upstreamProxy > url + + +
+ +| | | +| ------------ | -------- | +| **Type** | `string` | +| **Required** | No | +| **Format** | `uri` | + +**Description:** Proxy URL used for outbound connections to upstream Git hosts when set. +
+
+ + 24.3. [Optional] Property GitProxy configuration file > upstreamProxy > noProxy + + +
+ +| | | +| ------------ | ----------------- | +| **Type** | `array of string` | +| **Required** | No | + +**Description:** Additional hostnames or domain suffixes that should bypass the upstream proxy. + +| Each item of this array must be | Description | +| --------------------------------------------- | ----------- | +| [noProxy items](#upstreamProxy_noProxy_items) | - | + +#### 24.3.1. GitProxy configuration file > upstreamProxy > noProxy > noProxy items + +| | | +| ------------ | -------- | +| **Type** | `string` | +| **Required** | No | +
@@ -2029,4 +2219,4 @@ Specific value: `"jwt"`
---------------------------------------------------------------------------------------------------------------------------- -Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-01-21 at 14:25:25 +0100 +Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-13 at 15:33:22 +0100