Skip to content

embedding: validate embedding base url before building API provider - #1204

Merged
zzet merged 1 commit into
mainfrom
fix/embedding-api-url-validation
Oct 31, 2026
Merged

zzet merged 1 commit into
mainfrom
fix/embedding-api-url-validation

Conversation

@zzet

@zzet zzet commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

Problem

NewAPIProvider (internal/embedding/api.go) stored the configured embedding endpoint verbatim, applying only strings.TrimRight(url, "/").
Any scheme/host was accepted: file:///gopher:///unix:// endpoints parsed but only failed at transport time, and any routable host was reachable — including the cloud-metadata range (e.g. 169.254.169.254), which an attacker could reach by pointing a repo-local embedding.api_url at an internal address. So a malformed or metadata-targeting URL could steer the daemon's embedding traffic to a target it couldn't control.

Fix

Add ValidateEmbeddingAPIURL and enforce it at both construction points:

  • internal/embedding/provider.go — the .gortex.yaml embedding.api_url path (including repo-local config via NewProviderFromConfig).
  • internal/serverstack/embedder.go — the GORTEX_EMBEDDINGS_URL flag/env path.

An invalid endpoint returns an error there instead of building the provider, so the embedder degrades to the default text search. The gate requires an http/https scheme, a host, and rejects link-local (169.254.0.0/16, the cloud metadata range) and unspecified (0.0.0.0) addresses. Loopback (Ollama) and private/VPC hosts are allowed, since they aren't the unreachable-from-nowhere exfil targets link-local cloud metadata is.

Note

This gates the scheme/routability of any configured endpoint. The broader supply-chain question of whether a repo-local embedding.api_url should override global config without operator opt-in mirroring GORTEX_ALLOW_LOCAL_PROVIDERS is a separate concern.

Test

TestValidateEmbeddingAPIURL covers the ok/bad cases above. Existing embedding and serverstack suites pass unchanged.

NewAPIProvider stored the configured embedding endpoint verbatim, applying
only strings.TrimRight(url, "/"). Any scheme/host was accepted: a
non-http(s) scheme parsed but only failed at transport time, and any routable
host was reachable — including the cloud-metadata range 169.254.169.254, which
an attacker could reach by pointing a repo-local embedding.api_url at an
internal address. A malformed or metadata-targeting URL could thus steer
embedding traffic to a target it couldn't control.

Add ValidateEmbeddingAPIURL and enforce it at both construction points:
the .gortex.yaml embedding.api_url path (provider.go) and the
GORTEX_EMBEDDINGS_URL flag/env path (serverstack/embedder.go). An invalid
endpoint returns an error there instead of building the provider, so the
embedder degrades to the default text search. The gate requires an
http/https scheme and a host, and rejects link-local (cloud metadata) and
unspecified addresses while allowing loopback (Ollama) and private/VPC hosts.
@zzet
zzet merged commit 4ebc561 into main Oct 31, 2026
25 checks passed
@zzet
zzet deleted the fix/embedding-api-url-validation branch October 31, 2026 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant