add README and examples

This commit is contained in:
Ryan Mulligan 2020-09-03 13:16:44 -07:00
parent de367934a7
commit adc97bd3c5
11 changed files with 146 additions and 80 deletions

105
README.md
View file

@ -2,7 +2,10 @@
[age](https://github.com/FiloSottile/age)-encrypted secrets for NixOS.
# Features
It consists of a NixOS module `age`, and a CLI tool called `agenix`
used for editing and rekeying the secret files.
## Features
* Secrets are encrypted with SSH keys
** system public keys via `ssh-keyscan`
@ -10,11 +13,11 @@
* No GPG
* Very little code, so it should be easy for you to audit
# Installation
## Installation
Choose one of the following methods:
#### [niv](https://github.com/nmattia/niv) (Current recommendation)
### [niv](https://github.com/nmattia/niv) (Current recommendation)
First add it to niv:
@ -22,7 +25,9 @@ First add it to niv:
$ niv add ryantm/agenix
```
Than add the following to your configuration.nix in the `imports` list:
#### Module
Then add the following to your configuration.nix in the `imports` list:
```nix
{
@ -30,7 +35,7 @@ $ niv add ryantm/agenix
}
```
#### nix-channel
### nix-channel
As root run:
@ -47,11 +52,11 @@ $ nix-channel --update
}
```
#### fetchTarball
### fetchTarball
Add the following to your configuration.nix:
``` nix
```nix
{
imports = [ "${builtins.fetchTarball "https://github.com/ryantm/agenix/archive/master.tar.gz"}/modules/age" ];
}
@ -74,9 +79,11 @@ $ nix-channel --update
}
```
#### Flakes
### Flakes
``` nix
#### Module
```nix
{
inputs.agenix.url = "github:ryantm/agenix";
# optional, not necessary for the module
@ -96,6 +103,82 @@ $ nix-channel --update
}
```
# Tutorial
#### CLI
# Threat model
You don't need to install it:
```console
nix run github:ryantm/agenix -- --help
```
## Tutorial
1. Make a directory to store secrets and a YAML file for configuring encryption.
```console
$ mkdir secrets
$ cd secerts
$ touch secrets.yaml
```
2. Add public keys to `secrets.yaml` file (hint use `ssh-keyscan` or GitHub (for example, https://github.com/ryantm.keys):
```yaml
public_keys:
# users
- &user1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH
# systems
- &system1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE
secrets:
- name: secret1.age
public_keys:
- *user1
- *system1
- name: secret2.age
public_keys:
- *user1
```
3. Edit secret files (assuming your SSH private key is in ~/.ssh/):
```console
$ agenix -e secret1.age
```
4. Add secret to NixOS module config:
```nix
age.secrets.secret1 = ../secrets/secret1.age;
```
5. NixOS rebuild or use your deployment too like usual.
## Rekeying
If you change the public keys in `secrets.yaml`, you should rekey your
secrets:
```console
$ 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.
## Threat model/Warnings
This library has not be 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 repository 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 it is easier
to review configuration changes rather than 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`.
## Acknowledgements
This project is based off of
[sops-nix](https://github.com/Mic92/sops-nix) created Mic92. Thank you
to Mic92 for inspiration and help with making this.

View file

@ -1,16 +0,0 @@
public_keys:
# users
- &user1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFx3E0bHOWxRu91+XFzimbVA1mP19c5To/7szED1OUf9 user1@example.com
# hosts
# get these via ssh-keyscan
- &host1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKxk6NtiVv8L8R6/+lHgq4UP8P6JC7a6Wl2klCOOk8GP root@host1
secrets:
- name: secret.age
public_keys:
- *user1
- *host1
- name: other.age
public_keys:
- *user1
- *host1

BIN
example/secret1.age Normal file

Binary file not shown.

5
example/secret2.age Normal file
View file

@ -0,0 +1,5 @@
age-encryption.org/v1
-> ssh-ed25519 V3XmEA OB4+1FbPhQ3r6iGksM7peWX5it8NClpXIq/o5nnP7GA
FmHVUj+A5i5+bDFgySQskmlvynnosJiWUTJmBRiNA9I
--- tP+3mFVtd7ogVu1Lkboh55zoi5a77Ht08Uc/QuIviv4
¤¬Xæ{”ïOŠ£èätMXxÔvÓª(¬IÁmyPÇï¸è+3²S3i

14
example/secrets.yaml Normal file
View file

@ -0,0 +1,14 @@
public_keys:
# users
- &user1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH
# systems
- &system1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE
secrets:
- name: secret1.age
public_keys:
- *user1
- *system1
- name: secret2.age
public_keys:
- *user1

7
example_keys/system1 Normal file
View file

@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDyQ8iK/xUs9XCXXKFuvUfja1s8Biv/t4Caag9bfC9sxAAAAJA3yvCWN8rw
lgAAAAtzc2gtZWQyNTUxOQAAACDyQ8iK/xUs9XCXXKFuvUfja1s8Biv/t4Caag9bfC9sxA
AAAEA+J2V6AG1NriAIvnNKRauIEh1JE9HSdhvKJ68a5Fm0w/JDyIr/FSz1cJdcoW69R+Nr
WzwGK/+3gJpqD1t8L2zEAAAADHJ5YW50bUBob21lMQE=
-----END OPENSSH PRIVATE KEY-----

1
example_keys/system1.pub Normal file
View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE

7
example_keys/user1 Normal file
View file

@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACC9InTb4BornFoLqf5j+/M8gtt7hY2KtHr3FnYxkFGgRwAAAJC2JJ8htiSf
IQAAAAtzc2gtZWQyNTUxOQAAACC9InTb4BornFoLqf5j+/M8gtt7hY2KtHr3FnYxkFGgRw
AAAEDxt5gC/s53IxiKAjfZJVCCcFIsdeERdIgbYhLO719+Kb0idNvgGiucWgup/mP78zyC
23uFjYq0evcWdjGQUaBHAAAADHJ5YW50bUBob21lMQE=
-----END OPENSSH PRIVATE KEY-----

1
example_keys/user1.pub Normal file
View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH

View file

@ -6,16 +6,19 @@ PACKAGE="agenix"
function show_help () {
echo "$PACKAGE - edit and rekey age secret files"
echo " "
echo "$PACKAGE -e FILE"
echo "$PACKAGE -r"
echo "$PACKAGE -e FILE [-i PRIVATE_KEY]"
echo "$PACKAGE -r [-i PRIVATE_KEY]"
echo ' '
echo 'options:'
echo '-h, --help show help'
echo '-e, --edit FILE edits FILE using $EDITOR'
echo '-r, --rekey re-encrypts all secrets with specified recipients'
echo '-i, --identity identity to use when decrypting'
echo ' '
echo 'FILE an age-encrypted file'
echo ' '
echo 'PRIVATE_KEY a path to a private SSH key used to decrypt file'
echo ' '
echo 'EDITOR environment variable of editor to use when editing FILE'
echo ' '
echo 'RULES environment variable with path to YAML file specifying recipient public keys.'
@ -25,6 +28,7 @@ function show_help () {
test $# -eq 0 && (show_help && exit 1)
REKEY=0
DECRYPT=(--decrypt)
while test $# -gt 0; do
case "$1" in
@ -37,7 +41,17 @@ while test $# -gt 0; do
if test $# -gt 0; then
export FILE=$1
else
echo "no file specified"
echo "no FILE specified"
exit 1
fi
shift
;;
-i|--identity)
shift
if test $# -gt 0; then
DECRYPT+=(--identity "$1")
else
echo "no PRIVATE_KEY specified"
exit 1
fi
shift
@ -81,7 +95,6 @@ function edit {
if [ -f "$FILE" ]
then
DECRYPT=(--decrypt)
while IFS= read -r key
do
DECRYPT+=(--identity "$key")

View file

@ -1,49 +0,0 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p age yq-go moreutils
while test $# -gt 0; do
case "$1" in
-h|--help)
echo "$package - attempt to capture frames"
echo " "
echo "$package [options] application [arguments]"
echo " "
echo "options:"
echo "-h, --help show brief help"
echo "-a, --action=ACTION specify an action to use"
echo "-o, --output-dir=DIR specify a directory to store output in"
exit 0
;;
-a)
shift
if test $# -gt 0; then
export PROCESS=$1
else
echo "no process specified"
exit 1
fi
shift
;;
--action*)
export PROCESS=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
-o)
shift
if test $# -gt 0; then
export OUTPUT=$1
else
echo "no output dir specified"
exit 1
fi
shift
;;
--output-dir*)
export OUTPUT=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
*)
break
;;
esac
done