abhigyanpatwari/GitNexus · warning

AZURE_DEVOPS_URL is configured over cleartext http:// — the

Error message

AZURE_DEVOPS_URL is configured over cleartext http:// — the Azure DevOps PAT will be sent unencrypted. Prefer https:// where your instance supports it.

What it means

At server startup, warnIfInsecureAzureConfig inspects AZURE_DEVOPS_URL; if it parses and its scheme is http:, this one-time warning fires because the Azure DevOps PAT used for clones would cross the wire unencrypted on every request. The configuration is deliberately not refused (self-hosted instances that only serve http remain supported), but the risk is surfaced at boot because operators rarely read request-time logs.

Source

Thrown at gitnexus/src/server/git-clone.ts:294

    return host === 'dev.azure.com' || host.endsWith('.visualstudio.com');
  } catch {
    return false;
  }
}

/**
 * One-time startup warning when AZURE_DEVOPS_URL is configured over cleartext
 * http:// — the Azure DevOps PAT would then be sent unencrypted on every
 * clone. Self-hosted instances that only serve http are still supported (we
 * do not refuse), but operators rarely read request-time logs, so surface it
 * at boot too. Call once from server startup.
 */
export function warnIfInsecureAzureConfig(): void {
  const base = process.env.AZURE_DEVOPS_URL;
  if (!base) return;
  try {
    if (new URL(base).protocol === 'http:') {
      logger.warn(
        'AZURE_DEVOPS_URL is configured over cleartext http:// — the Azure DevOps PAT will be sent unencrypted. Prefer https:// where your instance supports it.',
      );
    }
  } catch {
    /* invalid AZURE_DEVOPS_URL — isAzureDevOpsUrl already tolerates this */
  }
}

export function buildCloneArgs(url: string, targetDir: string): string[] {
  return ['clone', '--depth', '1', '--', url, targetDir];
}

/**
 * Normalize a git URL into a comparable form.
 *
 * Two URLs are considered the same repository when their normalized forms
 * are identical: lowercased hostname, no trailing `.git`, no trailing
 * slashes on the path, default port stripped. Path comparison stays

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Serve the instance over https and set AZURE_DEVOPS_URL to the https:// base
  2. Put a TLS-terminating reverse proxy in front of the http instance and point AZURE_DEVOPS_URL at the https endpoint
  3. If cleartext is intentional on an isolated trusted network, accept the advisory warning: the clone still proceeds

Example fix

# before
export AZURE_DEVOPS_URL=http://tfs.internal:8080/

# after
export AZURE_DEVOPS_URL=https://tfs.internal/
Defensive patterns

Strategy: validation

Validate before calling

const base = process.env.AZURE_DEVOPS_URL;
if (base) {
  const u = new URL(base); // throws on invalid, mirroring the tolerant path
  if (u.protocol === 'http:') {
    throw new Error('AZURE_DEVOPS_URL must use https:// when a PAT will be sent');
  }
}

Prevention

When it happens

Trigger: Setting AZURE_DEVOPS_URL to any cleartext URL (e.g. http://tfs.internal:8080) and starting the server: every subsequent authenticated Azure DevOps clone sends the PAT base64-encoded but unencrypted. An invalid URL stays silent here because isAzureDevOpsUrl already tolerates it.

Common situations: Self-hosted Azure DevOps Server / TFS on plain http inside the corporate network; a copy-pasted internal URL; TLS terminated at a proxy while the configured base URL still uses http.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20). Data as JSON: /api/errors/4abbf9f50547ae56. Report an issue: GitHub.