Supply Chain Integrity
Python Libraries
All Python dependencies are sourced exclusively from PyPI over HTTPS. No private indexes or mirrors are used.
uv manages the dependency tree. uv.lock
records the exact version and SHA-256 hash of every package in the full
transitive closure. uv sync --frozen verifies each downloaded wheel against
its recorded hash before installation — a mismatch is a hard error.
UV Bootstrap
The installation script setup.ps1 bootstraps uv by downloading the official
uv-{arch}-pc-windows-msvc.zip binary archive from GitHub releases. The
archive is never executed. uv.exe is extracted from it and placed inside
the Vocalance install tree at %LOCALAPPDATA%\Programs\Vocalance\tools\uv.exe.
No system-wide UV installation occurs.
Before extraction, the script verifies the archive’s SHA-256 against a value computed offline and hard-coded at development time:
$UV_VERSION = '0.11.22'
$UV_ZIP_SHA256 = @{
'x86_64' = '<hex digest>'
'aarch64' = '<hex digest>'
}
$actual = (Get-FileHash -Path $uvZipPath -Algorithm SHA256).Hash.ToLower()
if ($actual -ne $UV_ZIP_SHA256[$arch].ToLower()) {
Remove-Item -LiteralPath $uvZipPath -Force -ErrorAction SilentlyContinue
throw "Integrity check failed ..."
}
The hashes are produced by
scripts/security/compute_uv_binary_hash.ps1
whenever a developer bumps $UV_VERSION. A mismatch deletes the downloaded
archive and aborts setup; uv.exe is never extracted from an unverified
archive.
AI Models
The AI model feature is optional (the installation script will ask the user whether they want to enable it — see Installation flow) and only a subset of dictation modes require it. When enabled, models are downloaded at first launch from Hugging Face.
Three controls are applied in sequence to every download.
Model allowlist
Only three models are permitted. The allowlist is hard-coded as a frozen Pydantic model in vocalance/app/config/app_config.py:
class LocalLLMArtifact(BaseModel):
model_config = ConfigDict(frozen=True)
id: str
repo_id: str
gguf_filenames: tuple[str, ...]
gguf_sha256: Dict[str, str] # filename → expected SHA-256
The three permitted models are:
qwen2.5-1.5b-q5km— Qwen2.5 1.5B Instruct (Q5_K_M)qwen3-4b-q5km— Qwen3 4B (Q5_K_M)qwen3-8b-q5km— Qwen3 8B (Q5_K_M)
Any model ID not in this list is rejected by the LLMConfig field validator
before a download is ever attempted.
Redirect pinning
Hugging Face CDN downloads are often served via HTTP redirect. Before following any redirect, the downloader validates that the target hostname is present in a hard-coded allowlist of trusted Hugging Face infrastructure domains:
_TRUSTED_HF_HOSTS = frozenset({
"huggingface.co",
"cdn-lfs.huggingface.co",
"cdn-lfs-us-1.huggingface.co",
"hf.co",
"cdn-lfs.hf.co",
"cdn-lfs-us-1.hf.co",
"cdn-lfs-eu-1.hf.co",
"xethub.hf.co",
"cas-bridge.xethub.hf.co",
})
def _validate_hf_redirect(response: httpx.Response) -> None:
if response.is_redirect:
location = response.headers.get("location", "")
host = urlparse(location).hostname or ""
trusted = host in _TRUSTED_HF_HOSTS or any(
host.endswith(f".{h}") for h in _TRUSTED_HF_HOSTS
)
if not trusted:
raise ValueError(f"Blocked redirect to untrusted host: {host!r}")
The allowlist covers both the legacy huggingface.co CDN subdomains and the
current hf.co CDN (cdn-lfs-us-1.hf.co, cdn-lfs-eu-1.hf.co,
cdn-lfs.hf.co) as well as the XetHub storage bridge
(cas-bridge.xethub.hf.co) introduced in February 2025. A redirect to any
host not in this set, or not a subdomain of a listed host, aborts the download.
SHA-256 verification
Each gguf_sha256 entry holds the expected digest of the corresponding
.gguf file, computed offline by a developer using
scripts/security/compute_llm_hashes.py.
After every completed download:
actual = self._sha256_of_file(partial_path)
if actual != expected_sha256.lower():
os.remove(partial_path)
raise IntegrityError(
f"SHA-256 mismatch for {filename!r}: "
f"expected {expected_sha256} got {actual}"
)
A mismatch deletes the file and raises IntegrityError, surfaced to the user
as an explicit error. The application will not load a model that failed
verification.
Bundled Models
The YAMNet sound classifier and Vosk speech recognition model are embedded directly in the release zip and are never downloaded separately (no need for external integrity validation).