Schema
Schema Base Modules
Section titled “Schema Base Modules”Each of host, user, home configuration objects have freeform-types,
meaning you can assign any attribute into them as meta-data.
However, at times you might want to have shared meta-data between all hosts or all users.
The base modules, den.schema.* serve for this purpose.
They are not aspects, they are meta-data (the attributes of host) that aspects
can later read for providing configuration.
For example, instead of:
den.hosts.x86_64-linux.igloo = { hardened = true; # custom free-form metadata
# repetitive users.alice.classes = [ "homeManager" ]; users.bob.classes = [ "homeManager" ];};You can do:
# This is not an aspect, it is a meta-configuration of the host capabilities.den.schema.host = { host, lib, ... }: { options.hardened = lib.mkEnableOption "Is it secure"; config.hardened = lib.mkDefault true;};
# The meta-configuration module for all usersden.schema.user = { user, lib, ... }: { config.classes = lib.mkDefault [ "homeManager" ];};All hosts you create will be hardened = true by default. And aspects will
be able to read host.hardened value.
den.schema
Section titled “den.schema”Base modules merged into all hosts, users, or homes. den.schema is built on
top of gen-schema — each key is a schema
entity, and the registry exposes introspection attrs (e.g. _kindNames,
_topology, _edges) that the pipeline itself consumes.
| Option | Type | Description |
|---|---|---|
den.schema.conf | deferredModule | Applied to host, user, and home |
den.schema.host | deferredModule | Applied to all hosts (imports conf) |
den.schema.user | deferredModule | Applied to all users (imports conf) |
den.schema.home | deferredModule | Applied to all homes (imports conf) |
den.schema.aspect | deferredModule | Applied to all aspects (imported into every aspect submodule) — where den.lib.strict is applied for strict mode |
den.schema.conf = { lib, ... }: { # shared across all host/user/home declarations};den.schema.host = { ... }: { # host-specific base config};A schema entry also accepts attributes, stripped before the module merge and consumed by the resolution pipeline:
| Attribute | Type | Default | Description |
|---|---|---|---|
includes | listOf raw | [] | Aspects/policies activated for every entity of this kind |
excludes | listOf raw | [] | Aspects/policies suppressed for every entity of this kind |
isEntity | bool | computed | Whether the kind is a real entity (fan-out/policy target). Computed as true when the entry carries any content beyond collection keys; set it explicitly for content-free entity kinds (e.g. den.schema.flake-parts.isEntity = true) |
isolated | bool | false | Mark this kind’s scopes as isolated — when an ancestor collects its subtree, it cannot cross into an isolated scope (the isolated scope still collects its own content) |
parent | nullOr str | null | The enclosing entity kind (e.g. user.parent = "host"). Defines the entity schema DAG the pipeline uses for descendant fan-out and class-module arg promotion |
collisionPolicy | nullOr enum | null | Class-module collision policy for every entity of this kind (see Class Modules) |
# Activate a policy for every hostden.schema.host.includes = [ den.policies.host-to-peers ];See Policy Activation for how includes
drives activation.
Entity Kinds
Section titled “Entity Kinds”Entity kinds (host, user, home) are derived from the keys of den.schema.
The pipeline uses the kind name to dispatch policies and resolve entities. Adding
a key to den.schema registers a new entity kind. Den pre-registers fleet as an
empty kind used by the diagram and fleet-view machinery.
den.hosts
Section titled “den.hosts”Type: attrsOf systemType
Keyed by system string (e.g., "x86_64-linux"). Each system contains
host definitions as freeform attribute sets.
den.hosts.x86_64-linux.myhost = { users.vic = {};};Flat form
Section titled “Flat form”The system level can be omitted: declare system inside the host value and
Den normalizes it into the two-level form. Both forms coexist freely:
# Equivalent to den.hosts.x86_64-linux.myhost = { ...; };den.hosts.myhost = { system = "x86_64-linux"; users.vic = {};};Host options
Section titled “Host options”| Option | Type | Default | Description |
|---|---|---|---|
name | str | attr name | Configuration name |
hostName | str | name | Network hostname |
system | str | parent key | Platform (e.g., x86_64-linux) |
class | str | auto | "nixos" or "darwin" based on system |
aspect | raw | den.aspects.<name> | Resolved aspect attrset for this host |
description | str | auto | class.hostName@system |
resolved | raw | auto | Resolved aspect from context pipeline (see below) |
users | attrsOf userType | {} | User accounts on this host |
collisionPolicy | null | enum | null | Class module collision policy for this entity: "error", "den-wins", or "class-wins". See Class Modules. |
instantiate | raw | auto | OS builder function |
intoAttr | listOf str | auto | Flake output path |
* | den.schema.host options | Options from base module | |
* | free-form attributes |
instantiate defaults
Section titled “instantiate defaults”| Class | Default |
|---|---|
nixos | inputs.nixpkgs.lib.nixosSystem |
darwin | inputs.darwin.lib.darwinSystem |
systemManager | inputs.system-manager.lib.makeSystemConfig |
intoAttr defaults
Section titled “intoAttr defaults”| Class | Default |
|---|---|
nixos | [ "nixosConfigurations" name ] |
darwin | [ "darwinConfigurations" name ] |
systemManager | [ "systemConfigs" name ] |
den.hosts.<sys>.<host>.users
Section titled “den.hosts.<sys>.<host>.users”Type: attrsOf userType
User options
Section titled “User options”| Option | Type | Default | Description |
|---|---|---|---|
name | str | attr name | User configuration name |
userName | str | name | System account name |
classes | listOf str | [ "user" ] | Nix classes this user participates in |
aspect | raw | den.aspects.<name> | Resolved aspect attrset |
host | raw | parent host | The host this user belongs to |
collisionPolicy | null | enum | null | Class module collision policy: "error", "den-wins", or "class-wins". See Class Modules. |
resolved | raw | auto | Resolved aspect from context pipeline (see below) |
* | den.schema.user options | Options from base module | |
* | free-form attributes |
Freeform: additional attributes pass through to the user module.
den.homes
Section titled “den.homes”Type: attrsOf homeSystemType
Standalone home-manager configurations, keyed by system string. A key of the
form user@host binds the home to an existing host’s user; a bare key declares
an unbound standalone home.
den.homes.x86_64-linux.vic = {};Flat form
Section titled “Flat form”As with den.hosts, the system level can be omitted — put system inside
the home value (both forms coexist):
den.homes."tux@igloo" = { system = "x86_64-linux";};Home options
Section titled “Home options”| Option | Type | Default | Description |
|---|---|---|---|
name | str | parsed name | Home configuration name (the part before @ in a user@host key) |
userName | str | parsed name | User account name |
hostName | null | str | parsed host | Bound host name, or null for unbound standalone homes (the part after @) |
host | raw | resolved host | Bound host entity, or null when standalone |
user | raw | resolved user | Bound user entity, or null when standalone |
system | str | parent key | Platform system |
class | str | "homeManager" | Home management class |
aspect | raw | den.aspects.<name> | Resolved aspect attrset |
description | str | auto | home.name@system |
pkgs | raw | inputs.nixpkgs.legacyPackages.$sys | Nixpkgs instance |
instantiate | raw | inputs.home-manager.lib.homeManagerConfiguration | Builder |
collisionPolicy | null | enum | null | Class module collision policy: "error", "den-wins", or "class-wins". See Class Modules. |
resolved | raw | auto | Resolved aspect from context pipeline (see below) |
intoAttr | listOf str | [ "homeConfigurations" name ] | Output path |
* | den.schema.home options | Options from base module | |
* | free-form attributes |
Entity resolved
Section titled “Entity resolved”Every entity (host, user, home) has a resolved attribute — the aspect
produced by running the entity through the resolution pipeline. This is
auto-derived and used internally by mainModule to produce the entity’s
final configuration.