sini's NixOS homelab and workstation configuration repository.
Note
If you have any questions or suggestions, feel free to contact me via e-mail jason <at> json64 <dot> dev.
| Name | Description | Type | Arch |
|---|---|---|---|
| uplink | Ryzen 5950X (16/32) - 128GB - 10gbe - Intel Arc A310 - AV1 Transcoding / Router / k8s control | Server | x86_64-linux |
| axon-01 | MINISFORUM Venus UM790 Pro - Ryzen 9 7940HS (8/16) - 64GB - 2.5gbe - Radeon 780M - k8s node | Server | x86_64-linux |
| axon-02 | MINISFORUM Venus UM790 Pro - Ryzen 9 7940HS (8/16) - 64GB - 2.5gbe - Radeon 780M - k8s node | Server | x86_64-linux |
| axon-03 | MINISFORUM Venus UM790 Pro - Ryzen 9 7940HS (8/16) - 64GB - 2.5gbe - Radeon 780M - k8s node | Server | x86_64-linux |
| bitstream | GMKtec M6 - Ryzen 5 6600H (8/16) - 64GB - 2.5gbe - Radeon 660M - k8s node | Server | x86_64-linux |
| cortex | Ryzen 9950X3D (16/32) - 128GB - 10gbe - 7900XTX + 3090TI - Hybrid ML Server/Workstation/VFIO Gaming Rig | Workstation | x86_64-linux |
| spike | Razer Blade 16 (2023) - NixOS - 32GB ram - RTX 4090 (mobile) | Laptop | x86_64-linux |
| patch | M1 Macbook Air - 16gb / 1tb - macOS Sequoia 15.2 | Laptop | aarch64-darwin |
This configuration uses den for declarative multi-entity system management, with gen-schema for typed entity registries and scope-engine for hierarchical settings resolution.
Entity types are defined via gen-schema with strict validation, cross-registry refs, and identity hashing:
| Entity | Purpose |
|---|---|
environment |
Domain, networks, certs, delegation, service domains |
group |
Membership labels, transitive resolution, ACL gating |
host |
Channel, networking, settings, system-owner, facts |
user |
Identity (SSH, GPG), system config (uid, groups) |
cluster |
K8s cluster: role-based host discovery, networks |
Entities are resolved through a scope tree driven by policies:
fleet
+-> environment (fan out den.environments)
+-> host (match host.environment)
| +-> user (ACL-gated via group intersection)
+-> cluster (match cluster.environment)
+-> host (role-based membership)
User assignment is ACL-driven via fleet.user-access group mappings against den.users.registry, not den's built-in host-to-users policy.
Configuration is organized into 216 aspects across 13 categories:
| Category | Examples |
|---|---|
core/ |
nix, nixpkgs, boot, i18n, systemd, shell, security, impermanence |
network/ |
networking (systemd-networkd), openssh, tailscale, network-boot |
disk/ |
ZFS (root + disko layout), impermanence, btrfs, xfs |
hardware/ |
cpu-amd/intel, gpu-amd/nvidia, laptop, razer, performance |
desktop/ |
hyprland, kde, gnome, stylix, fonts |
apps/ |
browsers, dev tools, gaming, media, messaging, shell utilities |
services/ |
haproxy, nginx, k3s, vault, prometheus, kanidm, jellyfin |
roles/ |
workstation, server, dev, gaming, media, nix-builder |
secrets/ |
agenix + agenix-rekey integration, custom generators |
kubernetes/ |
argocd, cilium, cert-manager, storage, gateway-api |
virtualization/ |
libvirt, podman, microvm |
system/ |
ananicy |
devshell/ |
colmena CLI |
Aspects emit into class keys (nixos, darwin, homeManager) and quirks (firewall, persist, secrets, etc.). Roles are composite aspects that bundle features via includes.
Cross-cutting concerns collected from aspects and aggregated at host/user scope:
firewall persist cache persistHome cacheHome secrets resolved-users service-domains prometheus-targets k8s-manifests nix-builders host-addrs bgp-peers vault-peers
| Battery | Purpose |
|---|---|
agenix |
Secret management: agenix-rekey per host/user, identity keys, HM integration |
colmena |
Fleet deployment via colmena hive with per-channel nixpkgs |
nixidy |
K8s manifest collection per cluster via policy.instantiate |
| Class | Routes Into | Guard |
|---|---|---|
homeLinux |
homeManager |
host.system ends with -linux |
homeDarwin |
homeManager |
host.system ends with -darwin |
homeAarch64 |
homeManager |
host.system starts with aarch64- |
devshell |
flake-parts |
(always) |
Feature settings use scope-engine for demand-driven resolution with automatic precedence: aspect defaults -> environment -> host -> user. Override provenance tracking shows where each setting came from.
modules/den/
+-- schema/ Entity type definitions (host, environment, user, group, cluster)
+-- environments/ Environment instances (prod, dev)
+-- groups/ Group definitions (admins, system-access, ...)
+-- users/ User registry + per-user aspects
+-- hosts/ Host definitions + per-host aspects
+-- clusters/ Cluster definitions (axon)
+-- aspects/ 216 aspect modules across 13 categories
+-- policies/ Scope resolution policies (fleet, hosts, users, pipes)
+-- quirks/ Pipe data type declarations
+-- classes/ Custom class definitions + route policies
+-- batteries/ Agenix, colmena, nixidy integration
+-- scope-engine/ Settings + ACL resolution graphs
+-- defaults.nix Default includes, quirk collectors, user-aspect auto-include
Nix files (they're all flake-parts modules) are automatically imported. Nix files prefixed with an underscore are ignored. No literal path imports are used. This means files can be moved around and nested in directories freely.
Note
This pattern has been the inspiration of an auto-imports library, import-tree.
The following files in this repository are generated and checked using the ENHANCED files flake-parts module:
.gitignoreLICENSEREADME.md.sops.yaml.secrets/secrets-manifest.md
This at the top level of the flake.nix file:
nixConfig.abort-on-warn = true;Note
It does not currently catch all warnings Nix can produce, but perhaps only evaluation warnings.
