Skip to content

Commit

Permalink
+ docs many
Browse files Browse the repository at this point in the history
  • Loading branch information
oluceps committed Nov 14, 2024
1 parent bbc6eec commit 703fe42
Show file tree
Hide file tree
Showing 11 changed files with 358 additions and 34 deletions.
1 change: 1 addition & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
book
6 changes: 6 additions & 0 deletions docs/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[book]
authors = ["oluceps"]
language = "en"
multilingual = false
src = "src"
title = "vaultix manual"
34 changes: 0 additions & 34 deletions docs/prerequisits.md

This file was deleted.

10 changes: 10 additions & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Summary

<!-- - [different from other scheme](./diff.md) -->

- [Prerequisits](prerequisits.md)
- [setup](setup.md)
- [flake Option](./flake-option.md)
- [nixos Option](./nixos-option.md)
- [Advanced](advanced.md)
- [FaQ](faq.md)
File renamed without changes.
File renamed without changes.
61 changes: 61 additions & 0 deletions docs/src/flake-option.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## flakeModule Options


The Vaultix configuration option has two parts: in flake level and nixos module level. You need to set both to make it work.


Here is a flake module configuration, it should be written in your flake top-level or in flake module.

Commented options means its default value.

You could find the definition [here](https://github.com/oluceps/vaultix/blob/main/flake-module.nix)

```nix
flake.vaultix = {
nodes = self.nixosConfigurations;
identity = "/where/sec/age-yubikey-identity-7d5d5540.txt.pub";
# extraRecipients = [ ];
# cache = "./secrets/cache";
};
```

### node =

NixOS systems that allow vaultix to manage. Generally pass `self.nixosConfigurations` will work, if you're using framework like `colmena` that produced unstandard system outputs, you need manually convertion, there always some way. For example, for `colmena`:

```nix
nodes = inherit ((colmena.lib.makeHive self.colmena).introspect (x: x)) nodes;
```


### identity =

`Age identity file`.

Supports age native secrets (recommend protected with passphrase), this could be a:

+ **string**, of absolute path to your local age identity. Thus it can avoid loading identity to nix store.

+ **path**, relative to your age identity in your configuration repository. Note that writting path directly will copy your secrets into nix store, with **Global READABLE**.

This is THE identity that could decrypt all of your secret, take care of it.

> Every `path` in your nix configuration will load file to nix store, eventually shows as string of absolute path to nix store.
Since it inherited great compatibility of `age`, you could use [yubikey](https://github.com/str4d/age-plugin-yubikey). Feel free to test other plugins like [age tpm](https://github.com/Foxboron/age-plugin-tpm).



### extraRecipients =

Recipients used for backup. Any of identity of them will able to decrypt all secrets, like the `identity`.

> Changing this will not take effect to `renc` command output. The hash of host pub key re-encrypted filename is `blake3(encrypted secret content + host public key)`.
I personally don't recommend setting this.


### cache =

**String** of path that **relative** to flake root, used for storing host public key
re-encrypted secrets. It's default `./secrets/cache`.
File renamed without changes.
169 changes: 169 additions & 0 deletions docs/src/nixos-option.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# NixOS Module Options


Configurable option could be divided into 3 parts:

```nix
# configuration.nix
{
imports = [ inputs.vaultix.nixosModules.default ];
vaultix = {
settings = { ... };
secrets = { ... };
templates = { ... };
};
}
```

## Settings =
Literally.


<div id="dd"></div>

### decryptedDir: path str

Folder where secrets are symlinked to. Default is `/run/vaultix`.

### decryptedDirForUser: path str

Same as above, but for secrets and templates that required by user, which means needs to be initialize before user born.


<div id="dmp"></div>

### decryptedMountPoint: path str with no trailing slash
default is `/run/vaultix.d`

Where secrets are created before they are symlinked to `vaultix.settings.decryptedDir`

Vaultix use this machenism to implement atomic manage, like other secret managing schemes.

It decrypting secrets into this directory, with generation number like `/run/vaultix.d/1`, then symlink it to `decryptedDir`.

### hostKeys

`{ path: str, type: str }`

default is `config.services.openssh.hostKeys`

This generally has no need to manually change, unless you know clearly what you're doing.

Ed25519 host private ssh key (identity) path that used for decrypting secrets while deploying.

format:

```nix
[
{
path = "/path/to/ssh_host_ed25519_key";
type = "ed25519";
}
]
```

### hostPubkey: str

ssh public key of the private key, which defines above. This is different from every host, since each generates host key while initial booting.

Get this by: `ssh-keyscan ip`. It supports `ed25519` type.

---

## Secrets = { }

Here is a secrets:
```nix
secrets = {
example = {
file = ./secret/example.age;
};
};
```
The secret is expected to appear in `/run/vaultix/` with `0400` and own by uid0.

Here is full options that configurable:

```nix
secrets = {
example = {
file = ./secret/example.age;
mode = "640"; # default 400
owner = "root";
group = "users";
name = "example.toml";
path = "/some/place";
neededForUser = false;
};
};
```

This part basically keeps identical with `agenix`. But has few diffs:

+ no `symlink: bool` option, since it has an systemd function called [tmpfiles.d](https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html).
+ added `neededForUser: bool` option, for deploying secrets and templates that required before user init.

### path: path str

If you manually set this, it will deploy to specified location instead of to `/run/vaultix.d` (default value of [decryptedMountPoint](#dmp)).

If you still set the path to directory to `/run/vaultix` (default value of [decryptedDir](#dd)), you will receive a warning, because you should use the `name` option instead of doing that.


## Templates

`Vaultix` provides templating function. This makes it able to insert secrets content into plaintext config while deploying.

Overview of this option:

```nix
templates = {
test-template = {
name = "template.txt";
content = "this is a template for testing ${config.vaultix.placeholder.example}";
trim = true;
# permission options like secrets
mode = "640"; # default 400
owner = "root";
group = "users";
name = "example.toml";
path = "/some/place";
neededForUser = false;
};
}
```


### content: str


To insert secrets in this string, insert `config.vaultix.placeholder.example`.

This pretend the secret which `id` (the keyof attribute of secrets) was defined.

```nix
secrets = {
# the id is example. despite `name`.
example = {
file = ./secret/example.age;
};
};
```

The content could also be multiline:
```nix
''
this is a template for testing ${config.vaultix.placeholder.example}
this is another ${config.vaultix.placeholder.what}
${config.vaultix.placeholder.some} here
''
```

TO BE NOTICE that the source secret file may have trailing `\n`:

### trim: bool

default true;

Removing trailing and leading whitespace by default.
51 changes: 51 additions & 0 deletions docs/src/prerequisits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Prerequisits

It basically require:

+ `nix-command` feature enabled
+ `flake-parts` structured config
+ `self` as one of `specialArgs` for nixosSystem
+ `systemd.sysusers` or `services.userborn` option enabled

See following for reason and details.

---

> enable `nix-command` `flakes` features
Which is almost every user will do.

Vaultix depends on nix flake and nix apps to perform basic function.

```nix
nix.settings = {
experimental-features = [
"nix-command"
"flakes"
];
}
```

---

> `flake-parts` structured config
[flake-parts](https://flake.parts/) provides modulized flake config, vaultix using [flake module](https://github.com/oluceps/vaultix/blob/main/flake-module.nix) to produce nix apps and hidding complexity.

---

> `self` as one of `specialArgs` for nixosSystem
For passing top-level flake arguments to nixos module.

This requirement may change in the future, with backward compatiblility. Looking forward for a better implementation in nixpkgs that more gracefully to do so.

---

> enable `systemd.sysusers` or `services.userborn`
`sysusers` was comes with [Perlless Activation](https://github.com/NixOS/nixpkgs/pull/270727).

`userborn` was introduced in [Aug 30 2024](https://github.com/NixOS/nixpkgs/pull/332719)

Vaultix using systemd instead of old perl script for activating on system startup or switch. It meams that you need on `nixos-24.05` or newer version for using it.
60 changes: 60 additions & 0 deletions docs/src/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# setup

You could also find the minimal complete nixos configuration on [CI VM test](https://github.com/oluceps/vaultix/tree/main/dev).

### Layout Preview

```nix
{
withSystem,
self,
inputs,
...
}:
{
flake = {
vaultix = {
nodes = self.nixosConfigurations;
identity = "/home/who/key";
};
nixosConfigurations.host-name = withSystem "x86_64-linux" ({ system, ... }:
inputs.nixpkgs.lib.nixosSystem (
{
inherit system;
specialArgs = {
inherit self; # Required
};
modules = [
inputs.oluceps.nixosModules.vaultix # import nixosModule
(
{ config, ... }:
{
services.userborn.enable = true; # or systemd.sysuser, required
vaultix = {
settings.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEu8luSFCts3g367nlKBrxMdLyOy4Awfo5Rb397ef2BC";
secrets.test-secret-1 = {
file = ./secrets/there-is-a-secret.age;
};
};
}
)
./configuration.nix
];
}
)
);
};
}
```
And you will be able to use secret on any module with, e.g.:

```
{
services.proxy1.environmentFile = config.vaultix.secrets.example.path;
}
# ...
```

0 comments on commit 703fe42

Please sign in to comment.