-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
Replace the current ad-hoc tooling installation (apt + curl | bash + manual version tracking) with Nix/devenv for declarative, reproducible, and cryptographically verified dependency management. This addresses regulatory requirements for medical device software (IEC 62304, FDA cybersecurity guidance) while eliminating the manual synchronization between Containerfile and EXPECTED_VERSIONS in tests.
Key benefits:
- Single source of truth for all tool versions (
flake.nix+flake.lock) - Cryptographic hash verification of all dependencies (supply chain security)
- Air-gapped/offline rebuild capability for regulatory compliance
- Automatic SBOM generation from dependency graph
- Reproducible builds years after initial release
Current Pain Points
1. Version tracking is manual and fragmented
Versions are scattered across:
Containerfile(implicit "latest" for gh, just, uv via curl)tests/test_image.pyEXPECTED_VERSIONSdict (manually maintained)
Updates are reactive—tests fail after rebuild, then we update the test file.
2. No reproducibility guarantee
# Current: fetches "latest" at build time
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/binBuilding the same Containerfile 3 months later produces different results.
3. Supply chain vulnerabilities
curl | bashpatterns trust remote scripts- apt packages trust Debian mirrors
- No cryptographic verification of most downloads (gh and uv have manual checksum verification, but just does not)
4. Regulatory gaps
- No built-in SBOM generation
- Difficult to prove "rebuild from source" capability
- No formal approval workflow for dependency updates
Proposed Solution: Nix/devenv
What changes
| Current | Proposed |
|---|---|
apt-get install git curl |
packages = [ pkgs.git pkgs.curl ] |
curl | bash for tools |
Nix packages with pinned hashes |
EXPECTED_VERSIONS in tests |
Derived from Nix metadata (or eliminated) |
| Implicit "latest" versions | Explicit pins in flake.lock |
Example devenv.nix
{ pkgs, ... }:
{
packages = [
pkgs.git
pkgs.curl
pkgs.gh
pkgs.just
pkgs.uv
pkgs.pre-commit
pkgs.ruff
];
languages.python = {
enable = true;
version = "3.12";
};
}flake.lock provides cryptographic pins
{
"nodes": {
"nixpkgs": {
"locked": {
"narHash": "sha256-abc123...",
"rev": "def456..."
}
}
}
}Regulatory Benefits (IEC 62304 / FDA)
1. Air-gapped/offline builds
# Archive all sources for offline rebuild
nix flake archive --json > archive-manifest.json
# Export binary cache
nix copy --to file:///path/to/offline-cache .#devcontainerEnables "rebuild without internet" for controlled manufacturing environments.
2. Supply chain protection
Every dependency is content-addressed:
- Source tarballs verified by SHA256
- Git commits verified by tree hash
- Build outputs verified by content hash
Hash mismatch = build failure (detects tampering automatically)
3. SBOM generation
nix derivation show .#devcontainer > sbom.jsonComplete dependency tree with versions, hashes, and sources.
4. Change control
# Diff between releases shows exactly what changed
diff release-1.0/flake.lock release-1.1/flake.lockflake.lock becomes a controlled document for regulatory submissions.
Update Workflow Comparison
| Update type | Current | With Nix |
|---|---|---|
| Patch | Automatic on rebuild (reactive) | nix flake update (proactive, controlled) |
| Minor | Automatic, may surprise | Explicit, reviewed before merge |
| Major | Manual Containerfile edit + test update | Change one line in devenv.nix |
| Rollback | Rebuild from git history, hope repos unchanged | git checkout flake.lock && nix build (identical) |
Security updates
- Stable nixpkgs channels backport security fixes
- Automated PRs via Renovate/Dependabot for
flake.lockupdates - Weekly update cadence recommended
Trade-offs
Costs
- Learning curve: Team needs Nix familiarity
- Image size: ~200-400 MB larger (Nix store overhead)
- Build time: Initial builds slower (Nix evaluation)
Mitigations
- Start with hybrid approach (Debian base + Nix for tools)
- Use binary cache to speed up builds
- Incremental adoption possible
Implementation Steps
- Evaluate devenv vs pure flake approach
- Create
flake.nixwith current tool set - Verify all tools available in nixpkgs (gh, just, uv, pre-commit, ruff)
- Set up binary cache (Cachix or self-hosted)
- Implement offline archive workflow
- Update tests to derive expected versions from Nix (or remove version checks)
- Document regulatory workflows (SBOM generation, approval process)
- Update CI pipeline
References
- devenv documentation
- Nix flakes
- Nix for reproducible builds
- FDA Cybersecurity Guidance
- IEC 62304 - Medical device software lifecycle
cc @c-vigo for discussion