From 657789137cc504ba6a6bed7b72254f2626550967 Mon Sep 17 00:00:00 2001 From: Ryan Mulligan Date: Sun, 26 Feb 2023 14:17:37 -0800 Subject: [PATCH] doc: add new doc website * use mmdoc * add github pages action to auto publish * do not edit README for now, will follow up with a commit directs people to the doc site --- .github/workflows/ci.yaml | 2 + .github/workflows/doc.yml | 36 +++++ doc/acknowledgements.md | 3 + doc/community-and-support.md | 4 + doc/contributing.md | 28 ++++ doc/features.md | 8 + doc/install-via-fetchtarball.md | 38 +++++ doc/install-via-flakes.md | 39 +++++ doc/install-via-niv.md | 27 ++++ doc/install-via-nix-channel.md | 28 ++++ doc/introduction.md | 3 + doc/notices.md | 3 + doc/overriding-age-binary.md | 12 ++ doc/problem-and-solution.md | 5 + doc/reference.md | 250 ++++++++++++++++++++++++++++++++ doc/rekeying.md | 13 ++ doc/threat-model-warnings.md | 14 ++ doc/toc.md | 18 +++ doc/tutorial.md | 51 +++++++ flake.lock | 6 +- flake.nix | 6 + pkgs/doc.nix | 11 ++ 22 files changed, 602 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/doc.yml create mode 100644 doc/acknowledgements.md create mode 100644 doc/community-and-support.md create mode 100644 doc/contributing.md create mode 100644 doc/features.md create mode 100644 doc/install-via-fetchtarball.md create mode 100644 doc/install-via-flakes.md create mode 100644 doc/install-via-niv.md create mode 100644 doc/install-via-nix-channel.md create mode 100644 doc/introduction.md create mode 100644 doc/notices.md create mode 100644 doc/overriding-age-binary.md create mode 100644 doc/problem-and-solution.md create mode 100644 doc/reference.md create mode 100644 doc/rekeying.md create mode 100644 doc/threat-model-warnings.md create mode 100644 doc/toc.md create mode 100644 doc/tutorial.md create mode 100644 pkgs/doc.nix diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a54ed78..7a765e3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -11,6 +11,7 @@ jobs: with: extra_nix_config: "system-features = nixos-test benchmark big-parallel kvm" - run: nix build + - run: nix build .#doc - run: nix fmt . -- --check - run: nix flake check tests-darwin: @@ -21,6 +22,7 @@ jobs: with: extra_nix_config: "system-features = nixos-test benchmark big-parallel kvm" - run: nix build + - run: nix build .#doc - run: nix fmt . -- --check - run: nix flake check - run: | diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml new file mode 100644 index 0000000..c8569c3 --- /dev/null +++ b/.github/workflows/doc.yml @@ -0,0 +1,36 @@ +name: doc + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + publish: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v20 + - run: nix build .#doc + - name: Setup Pages + uses: actions/configure-pages@v3 + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: 'result/multi' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 diff --git a/doc/acknowledgements.md b/doc/acknowledgements.md new file mode 100644 index 0000000..cd36955 --- /dev/null +++ b/doc/acknowledgements.md @@ -0,0 +1,3 @@ +# Acknowledgements {#acknowledgements} + +This project is based off of [sops-nix](https://github.com/Mic92/sops-nix) created Mic92. Thank you to Mic92 for inspiration and advice. diff --git a/doc/community-and-support.md b/doc/community-and-support.md new file mode 100644 index 0000000..831b046 --- /dev/null +++ b/doc/community-and-support.md @@ -0,0 +1,4 @@ +# Community and Support {#community-and-support} + +Support and development discussion is available here on GitHub and +also through [Matrix](https://matrix.to/#/#agenix:nixos.org). diff --git a/doc/contributing.md b/doc/contributing.md new file mode 100644 index 0000000..4954726 --- /dev/null +++ b/doc/contributing.md @@ -0,0 +1,28 @@ +# Contributing {#contributing} + +* The main branch is protected against direct pushes +* All changes must go through GitHub PR review and get at least one approval +* PR titles and commit messages should be prefixed with at least one of these categories: + * contrib - things that make the project development better + * doc - documentation + * feature - new features + * fix - bug fixes +* Please update or make integration tests for new features +* Use `nix fmt` to format nix code + + +## Tests + +You can run the tests with + +```ShellSession +nix flake check +``` + +You can run the integration tests in interactive mode like this: + +```ShellSession +nix run .#checks.x86_64-linux.integration.driverInteractive +``` + +After it starts, enter `run_tests()` to run the tests. diff --git a/doc/features.md b/doc/features.md new file mode 100644 index 0000000..fc74bc3 --- /dev/null +++ b/doc/features.md @@ -0,0 +1,8 @@ +# Features {#features} + +* Secrets are encrypted with SSH keys + * system public keys via `ssh-keyscan` + * can use public keys available on GitHub for users (for example, https://github.com/ryantm.keys) +* No GPG +* Very little code, so it should be easy for you to audit +* Encrypted secrets are stored in the Nix store, so a separate distribution mechanism is not necessary diff --git a/doc/install-via-fetchtarball.md b/doc/install-via-fetchtarball.md new file mode 100644 index 0000000..d6f5b08 --- /dev/null +++ b/doc/install-via-fetchtarball.md @@ -0,0 +1,38 @@ +# Install via fetchTarball {#install-via-fetchtarball} + +#### Install module via fetchTarball + +Add the following to your configuration.nix: + +```nix +{ + imports = [ "${builtins.fetchTarball "https://github.com/ryantm/agenix/archive/main.tar.gz"}/modules/age.nix" ]; +} +``` + + or with pinning: + +```nix +{ + imports = let + # replace this with an actual commit id or tag + commit = "298b235f664f925b433614dc33380f0662adfc3f"; + in [ + "${builtins.fetchTarball { + url = "https://github.com/ryantm/agenix/archive/${commit}.tar.gz"; + # update hash from nix build output + sha256 = ""; + }}/modules/age.nix" + ]; +} +``` + +#### Install CLI via fetchTarball + +To install the `agenix` binary: + +```nix +{ + environment.systemPackages = [ (pkgs.callPackage "${builtins.fetchTarball "https://github.com/ryantm/agenix/archive/main.tar.gz"}/pkgs/agenix.nix" {}) ]; +} +``` diff --git a/doc/install-via-flakes.md b/doc/install-via-flakes.md new file mode 100644 index 0000000..efb7e4b --- /dev/null +++ b/doc/install-via-flakes.md @@ -0,0 +1,39 @@ +# Install via Flakes {#install-via-flakes} + +## Install module via Flakes + +```nix +{ + inputs.agenix.url = "github:ryantm/agenix"; + # optional, not necessary for the module + #inputs.agenix.inputs.nixpkgs.follows = "nixpkgs"; + + outputs = { self, nixpkgs, agenix }: { + # change `yourhostname` to your actual hostname + nixosConfigurations.yourhostname = nixpkgs.lib.nixosSystem { + # change to your system: + system = "x86_64-linux"; + modules = [ + ./configuration.nix + agenix.nixosModules.default + ]; + }; + }; +} +``` + +## Install CLI via Flakes + +You don't need to install it, + +```ShellSession +nix run github:ryantm/agenix -- --help +``` + +but, if you want to (change the system based on your system): + +```nix +{ + environment.systemPackages = [ agenix.packages.x86_64-linux.default ]; +} +``` diff --git a/doc/install-via-niv.md b/doc/install-via-niv.md new file mode 100644 index 0000000..7aba6f4 --- /dev/null +++ b/doc/install-via-niv.md @@ -0,0 +1,27 @@ +# Install via [niv](https://github.com/nmattia/niv) {#install-via-niv} + +First add it to niv: + +```ShellSession +$ niv add ryantm/agenix +``` + +## Install module via niv + +Then add the following to your `configuration.nix` in the `imports` list: + +```nix +{ + imports = [ "${(import ./nix/sources.nix).agenix}/modules/age.nix" ]; +} +``` + +## Install CLI via niv + +To install the `agenix` binary: + +```nix +{ + environment.systemPackages = [ (pkgs.callPackage "${(import ./nix/sources.nix).agenix}/pkgs/agenix.nix" {}) ]; +} +``` diff --git a/doc/install-via-nix-channel.md b/doc/install-via-nix-channel.md new file mode 100644 index 0000000..75c8d86 --- /dev/null +++ b/doc/install-via-nix-channel.md @@ -0,0 +1,28 @@ +# Install via nix-channel {#install-via-nix-channel} + +As root run: + +```ShellSession +$ sudo nix-channel --add https://github.com/ryantm/agenix/archive/main.tar.gz agenix +$ sudo nix-channel --update +``` + +## Install module via nix-channel + +Then add the following to your `configuration.nix` in the `imports` list: + +```nix +{ + imports = [ ]; +} +``` + +## Install CLI via nix-channel + +To install the `agenix` binary: + +```nix +{ + environment.systemPackages = [ (pkgs.callPackage {}) ]; +} +``` diff --git a/doc/introduction.md b/doc/introduction.md new file mode 100644 index 0000000..58ff3a5 --- /dev/null +++ b/doc/introduction.md @@ -0,0 +1,3 @@ +# agenix - [age](https://github.com/FiloSottile/age)-encrypted secrets for NixOS {#introduction} + +`agenix` is a commandline tool for managing secrets encrypted with your existing SSH keys. This project also includes the NixOS module `age` for adding encrypted secrets into the Nix store and decrypting them. diff --git a/doc/notices.md b/doc/notices.md new file mode 100644 index 0000000..5dcc5a9 --- /dev/null +++ b/doc/notices.md @@ -0,0 +1,3 @@ +# Notices {#notices} + +* Password-protected ssh keys: since the underlying tool age/rage do not support ssh-agent, password-protected ssh keys do not work well. For example, if you need to rekey 20 secrets you will have to enter your password 20 times. diff --git a/doc/overriding-age-binary.md b/doc/overriding-age-binary.md new file mode 100644 index 0000000..9ee3a11 --- /dev/null +++ b/doc/overriding-age-binary.md @@ -0,0 +1,12 @@ +# Overriding age binary {#overriding-age-binary} + +The agenix CLI uses `rage` by default as its age implemenation, you +can use the reference implementation `age` with Flakes like this: + +```nix +{pkgs,agenix,...}:{ + environment.systemPackages = [ + (agenix.packages.x86_64-linux.default.override { ageBin = "${pkgs.age}/bin/age"; }) + ]; +} +``` diff --git a/doc/problem-and-solution.md b/doc/problem-and-solution.md new file mode 100644 index 0000000..fb2b758 --- /dev/null +++ b/doc/problem-and-solution.md @@ -0,0 +1,5 @@ +# Problem and solution {#problem-and-solution} + +All files in the Nix store are readable by any system user, so it is not a suitable place for including cleartext secrets. Many existing tools (like NixOps deployment.keys) deploy secrets separately from `nixos-rebuild`, making deployment, caching, and auditing more difficult. Out-of-band secret management is also less reproducible. + +`agenix` solves these issues by using your pre-existing SSH key infrastructure and `age` to encrypt secrets into the Nix store. Secrets are decrypted using an SSH host private key during NixOS system activation. diff --git a/doc/reference.md b/doc/reference.md new file mode 100644 index 0000000..614b0c9 --- /dev/null +++ b/doc/reference.md @@ -0,0 +1,250 @@ +# Reference {#reference} + +## `age` module reference {#age-module-reference} + +### `age.secrets` + +`age.secrets` attrset of secrets. You always need to use this +configuration option. Defaults to `{}`. + +### `age.secrets..file` + +`age.secrets..file` is the path to the encrypted `.age` for this +secret. This is the only required secret option. + +Example: + +```nix +{ + age.secrets.monitrc.file = ../secrets/monitrc.age; +} +``` + +### `age.secrets..path` + +`age.secrets..path` is the path where the secret is decrypted +to. Defaults to `/run/agenix/` (`config.age.secretsDir/`). + +Example defining a different path: + +```nix +{ + age.secrets.monitrc = { + file = ../secrets/monitrc.age; + path = "/etc/monitrc"; + }; +} +``` + +For many services, you do not need to set this. Instead, refer to the +decryption path in your configuration with +`config.age.secrets..path`. + +Example referring to path: + +```nix +{ + users.users.ryantm = { + isNormalUser = true; + passwordFile = config.age.secrets.passwordfile-ryantm.path; + }; +} +``` + +#### builtins.readFile anti-pattern + +```nix +{ + # Do not do this! + config.password = builtins.readFile config.age.secrets.secret1.path; +} +``` + +This can cause the cleartext to be placed into the world-readable Nix +store. Instead, have your services read the cleartext path at runtime. + +### `age.secrets..mode` + +`age.secrets..mode` is permissions mode of the decrypted secret +in a format understood by chmod. Usually, you only need to use this in +combination with `age.secrets..owner` and +`age.secrets..group` + +Example: + +```nix +{ + age.secrets.nginx-htpasswd = { + file = ../secrets/nginx.htpasswd.age; + mode = "770"; + owner = "nginx"; + group = "nginx"; + }; +} +``` + +### `age.secrets..owner` + +`age.secrets..owner` is the username of the decrypted file's +owner. Usually, you only need to use this in combination with +`age.secrets..mode` and `age.secrets..group` + +Example: + +```nix +{ + age.secrets.nginx-htpasswd = { + file = ../secrets/nginx.htpasswd.age; + mode = "770"; + owner = "nginx"; + group = "nginx"; + }; +} +``` + +### `age.secrets..group` + +`age.secrets..group` is the name of the decrypted file's +group. Usually, you only need to use this in combination with +`age.secrets..owner` and `age.secrets..mode` + +Example: + +```nix +{ + age.secrets.nginx-htpasswd = { + file = ../secrets/nginx.htpasswd.age; + mode = "770"; + owner = "nginx"; + group = "nginx"; + }; +} +``` + +### `age.secrets..symlink` + +`age.secrets..symlink` is a boolean. If true (the default), +secrets are symlinked to `age.secrets..path`. If false, secerts +are copied to `age.secrets..path`. Usually, you want to keep +this as true, because it secure cleanup of secrets no longer +used. (The symlink will still be there, but it will be broken.) If +false, you are responsible for cleaning up your own secrets after you +stop using them. + +Some programs do not like following symlinks (for example Java +programs like Elasticsearch). + +Example: + +```nix +{ + age.secrets."elasticsearch.conf" = { + file = ../secrets/elasticsearch.conf.age; + symlink = false; + }; +} +``` + +### `age.secrets..name` + +`age.secrets..name` is the string of the name of the file after +it is decrypted. Defaults to the `` in the attrpath, but can be +set separately if you want the file name to be different from the +attribute name part. + +Example of a secret with a name different from its attrpath: + +```nix +{ + age.secrets.monit = { + name = "monitrc"; + file = ../secrets/monitrc.age; + }; +} +``` + +### `age.ageBin` + +`age.ageBin` the string of the path to the `age` binary. Usually, you +don't need to change this. Defaults to `rage/bin/rage`. + +Overriding `age.ageBin` example: + +```nix +{pkgs, ...}:{ + age.ageBin = "${pkgs.age}/bin/age"; +} +``` + +### `age.identityPaths` + +`age.identityPaths` is a list of paths to recipient keys to try to use to +decrypt the secrets. By default, it is the `rsa` and `ed25519` keys in +`config.services.openssh.hostKeys`, and on NixOS you usually don't need to +change this. The list items should be strings (`"/path/to/id_rsa"`), not +nix paths (`../path/to/id_rsa`), as the latter would copy your private key to +the nix store, which is the exact situation `agenix` is designed to avoid. At +least one of the file paths must be present at runtime and able to decrypt the +secret in question. Overriding `age.identityPaths` example: + +```nix +{ + age.identityPaths = [ "/var/lib/persistent/ssh_host_ed25519_key" ]; +} +``` + +### `age.secretsDir` + +`age.secretsDir` is the directory where secrets are symlinked to by +default.Usually, you don't need to change this. Defaults to +`/run/agenix`. + +Overriding `age.secretsDir` example: + +```nix +{ + age.secretsDir = "/run/keys"; +} +``` + +### `age.secretsMountPoint` + +`age.secretsMountPoint` is the directory where the secret generations +are created before they are symlinked. Usually, you don't need to +change this. Defaults to `/run/agenix.d`. + + +Overriding `age.secretsMountPoint` example: + +```nix +{ + age.secretsMountPoint = "/run/secret-generations"; +} +``` + +## agenix CLI reference {#agenix-cli-reference} + +``` +agenix - edit and rekey age secret files + +agenix -e FILE [-i PRIVATE_KEY] +agenix -r [-i PRIVATE_KEY] + +options: +-h, --help show help +-e, --edit FILE edits FILE using $EDITOR +-r, --rekey re-encrypts all secrets with specified recipients +-d, --decrypt FILE decrypts FILE to STDOUT +-i, --identity identity to use when decrypting +-v, --verbose verbose output + +FILE an age-encrypted file + +PRIVATE_KEY a path to a private SSH key used to decrypt file + +EDITOR environment variable of editor to use when editing FILE + +If STDIN is not interactive, EDITOR will be set to "cp /dev/stdin" + +RULES environment variable with path to Nix file specifying recipient public keys. +Defaults to './secrets.nix' diff --git a/doc/rekeying.md b/doc/rekeying.md new file mode 100644 index 0000000..4d56ad3 --- /dev/null +++ b/doc/rekeying.md @@ -0,0 +1,13 @@ +# Rekeying {#rekeying} + +If you change the public keys in `secrets.nix`, you should rekey your +secrets: + +```ShellSession +$ agenix --rekey +``` + +To rekey a secret, you have to be able to decrypt it. Because of +randomness in `age`'s encryption algorithms, the files always change +when rekeyed, even if the identities do not. (This eventually could be +improved upon by reading the identities from the age file.) diff --git a/doc/threat-model-warnings.md b/doc/threat-model-warnings.md new file mode 100644 index 0000000..f9c652c --- /dev/null +++ b/doc/threat-model-warnings.md @@ -0,0 +1,14 @@ +# Threat model/Warnings {#threat-model-warnings} + +This project has not been audited by a security professional. + +People unfamiliar with `age` might be surprised that secrets are not +authenticated. This means that every attacker that has write access to +the secret files can modify secrets because public keys are exposed. +This seems like not a problem on the first glance because changing the +configuration itself could expose secrets easily. However, reviewing +configuration changes is easier than reviewing random secrets (for +example, 4096-bit rsa keys). This would be solved by having a message +authentication code (MAC) like other implementations like GPG or +[sops](https://github.com/Mic92/sops-nix) have, however this was left +out for simplicity in `age`. diff --git a/doc/toc.md b/doc/toc.md new file mode 100644 index 0000000..e6b7238 --- /dev/null +++ b/doc/toc.md @@ -0,0 +1,18 @@ +# agenix + +* [Introduction](#introduction) +* [Problem and solution](#problem-and-solution) +* [Features](#features) +* Installation + * [flakes](#install-via-flakes) + * [niv](#install-via-niv) + * [fetchTarball](#install-via-fetchtarball) + * [nix-channel](#install-via-nix-channel) +* [Tutorial](#tutorial) +* [Reference](#reference) + * [`age` module reference](#age-module-reference) + * [agenix CLI reference](#agenix-cli-reference) +* [Community and Support](#community-and-support) +* [Threat model/Warnings](#threat-model-warnings) +* [Contributing](#contributing) +* [Acknowledgements](#acknowledgements) diff --git a/doc/tutorial.md b/doc/tutorial.md new file mode 100644 index 0000000..8344121 --- /dev/null +++ b/doc/tutorial.md @@ -0,0 +1,51 @@ +# Tutorial {#tutorial} + +1. The system you want to deploy secrets to should already exist and + have `sshd` running on it so that it has generated SSH host keys in + `/etc/ssh/`. + +2. Make a directory to store secrets and `secrets.nix` file for listing secrets and their public keys (This file is **not** imported into your NixOS configuration. It is only used for the `agenix` CLI.): + + ```ShellSession + $ mkdir secrets + $ cd secrets + $ touch secrets.nix + ``` +3. Add public keys to `secrets.nix` file (hint: use `ssh-keyscan` or GitHub (for example, https://github.com/ryantm.keys)): + ```nix + let + user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH"; + user2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILI6jSq53F/3hEmSs+oq9L4TwOo1PrDMAgcA1uo1CCV/"; + users = [ user1 user2 ]; + + system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE"; + system2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzxQgondgEYcLpcPdJLrTdNgZ2gznOHCAxMdaceTUT1"; + systems = [ system1 system2 ]; + in + { + "secret1.age".publicKeys = [ user1 system1 ]; + "secret2.age".publicKeys = users ++ systems; + } + ``` +4. Edit secret files (these instructions assume your SSH private key is in ~/.ssh/): + ```ShellSession + $ agenix -e secret1.age + ``` +5. Add secret to a NixOS module config: + ```nix + { + age.secrets.secret1.file = ../secrets/secret1.age; + } + ``` +6. Use the secret in your config: + ```nix + { + users.users.user1 = { + isNormalUser = true; + passwordFile = config.age.secrets.secret1.path; + }; + } + ``` +7. NixOS rebuild or use your deployment tool like usual. + + The secret will be decrypted to the value of `config.age.secrets.secret1.path` (`/run/agenix/secret1` by default). diff --git a/flake.lock b/flake.lock index df8a306..a73d62d 100644 --- a/flake.lock +++ b/flake.lock @@ -23,11 +23,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1674641431, - "narHash": "sha256-qfo19qVZBP4qn5M5gXc/h1MDgAtPA5VxJm9s8RUAkVk=", + "lastModified": 1677676435, + "narHash": "sha256-6FxdcmQr5JeZqsQvfinIMr0XcTyTuR7EXX0H3ANShpQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9b97ad7b4330aacda9b2343396eb3df8a853b4fc", + "rev": "a08d6979dd7c82c4cef0dcc6ac45ab16051c1169", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 143dd5f..6269b44 100644 --- a/flake.nix +++ b/flake.nix @@ -15,6 +15,7 @@ darwin, }: let agenix = system: nixpkgs.legacyPackages.${system}.callPackage ./pkgs/agenix.nix {}; + doc = system: nixpkgs.legacyPackages.${system}.callPackage ./pkgs/doc.nix {}; in { nixosModules.age = import ./modules/age.nix; nixosModules.default = self.nixosModules.age; @@ -26,23 +27,28 @@ formatter.x86_64-darwin = nixpkgs.legacyPackages.x86_64-darwin.alejandra; packages.x86_64-darwin.agenix = agenix "x86_64-darwin"; + packages.x86_64-darwin.doc = doc "x86_64-darwin"; packages.x86_64-darwin.default = self.packages.x86_64-darwin.agenix; formatter.aarch64-darwin = nixpkgs.legacyPackages.aarch64-darwin.alejandra; packages.aarch64-darwin.agenix = agenix "aarch64-darwin"; + packages.aarch64-darwin.doc = doc "aarch64-darwin"; packages.aarch64-darwin.default = self.packages.aarch64-darwin.agenix; formatter.aarch64-linux = nixpkgs.legacyPackages.aarch64-linux.alejandra; packages.aarch64-linux.agenix = agenix "aarch64-linux"; + packages.aarch64-linux.doc = doc "aarch64-linux"; packages.aarch64-linux.default = self.packages.aarch64-linux.agenix; formatter.i686-linux = nixpkgs.legacyPackages.i686-linux.alejandra; packages.i686-linux.agenix = agenix "i686-linux"; + packages.i686-linux.doc = doc "i686-linux"; packages.i686-linux.default = self.packages.i686-linux.agenix; formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.alejandra; packages.x86_64-linux.agenix = agenix "x86_64-linux"; packages.x86_64-linux.default = self.packages.x86_64-linux.agenix; + packages.x86_64-linux.doc = doc "x86_64-linux"; checks.x86_64-linux.integration = import ./test/integration.nix { inherit nixpkgs; pkgs = nixpkgs.legacyPackages.x86_64-linux; diff --git a/pkgs/doc.nix b/pkgs/doc.nix new file mode 100644 index 0000000..db441dc --- /dev/null +++ b/pkgs/doc.nix @@ -0,0 +1,11 @@ +{ + stdenvNoCC, + mmdoc, + self, +}: +stdenvNoCC.mkDerivation rec { + name = "agenix-doc"; + src = ../doc; + phases = ["mmdocPhase"]; + mmdocPhase = "${mmdoc}/bin/mmdoc agenix $src $out"; +}