Skip to content

Commit

Permalink
+ interface optimization
Browse files Browse the repository at this point in the history
~ trival improv
  • Loading branch information
oluceps committed Nov 4, 2024
1 parent d88bcc8 commit 1c187f5
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 62 deletions.
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ outputs = inputs@{ flake-parts, self, ... }:
inputs.vaultix.url = "github:oluceps/vaultix";
```

Adding nixosModule config:

```nix
# configuration.nix
{
Expand All @@ -50,13 +52,14 @@ inputs.vaultix.url = "github:oluceps/vaultix";
settings = {
# relative to flake root, used for storing host public key -
# re-encrypted secrets.
storageDirRelative = "./secret/renc/${config.networking.hostName}";
# extraRecipients = [ data.keys.ageKey ]; # not supported yet
masterIdentities = [
storageLocation = "./secret/renc/${config.networking.hostName}";
# extraRecipients =
# not supported yet, plain to used in edit command
# [ data.keys.ageKey ];
identity =
# See https://github.com/str4d/age-plugin-yubikey
# Also supports age native secrets
(self + "/secret/age-yubikey-identity-0000ffff.txt.pub")
];
# Also supports age native secrets (with password encrypted)
(self + "/secret/age-yubikey-identity-0000ffff.txt.pub");
};
secrets = {
example = {
Expand All @@ -65,7 +68,8 @@ inputs.vaultix.url = "github:oluceps/vaultix";
owner = "root";
group = "users";
name = "example.toml";
# path = "/some/place"; # not supported yet
# symlink = true; # both not supported yet
# path = "/some/place";
};
# ...
};
Expand All @@ -74,15 +78,15 @@ inputs.vaultix.url = "github:oluceps/vaultix";
```

> [!TIP]
> During first setup, you need to manually create `storageDirRelative` and
> During first setup, you need to manually create `storageLocation` and
> add it to git (create an placeholder since git ignores empty directory).
```bash
mkdir -p ./secret/renc/YOUR_HOSTNAME_HERE
touch ./secret/renc/YOUR_HOSTNAME_HERE/.placeholder
# so that you could add the directory to git (for recognizing by flake)
mkdir -p ./secret/renc/HOSTNAME_HERE
touch ./secret/renc/HOSTNAME_HERE/.placeholder
# So that you could add the directory to git (for recognizing by flake).
git add .
# after this step you could remove placeholder
# Freely could remove placeholder once complete this step.
nix run .#vaultix.x86_64-linux.renc
```

Expand Down
35 changes: 12 additions & 23 deletions module/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ let
options.systemd ? sysusers && (config.systemd.sysusers.enable || config.services.userborn.enable)
) "`systemd.sysusers` or `services.userborn` must be enabled.";

storagePath = self + "/" + cfg.settings.storageDirRelative;
storagePath = self + "/" + cfg.settings.storageLocation;
storageExist = assertMsg (builtins.pathExists storagePath) "${storagePath} doesn't exist plz manually create and add to git first (may need a placeholder for git to recognize it)";

settingsType = types.submodule (submod: {
options = {

storageDirRelative = mkOption {
storageLocation = mkOption {
type = types.str;
example = literalExpression ''./. /* <- flake root */ + "/secrets/renced/myhost" /* separate folder for each host */'';
description = ''
The local storage directory for re-encrypted secrets. MUST be a str of path related to flake root.
'';
};
storageDirStore = mkOption {
storageInStore = mkOption {
type = types.path;
readOnly = true;
default = builtins.path { path = self + "/" + submod.config.storageDirRelative; };
default = builtins.path { path = self + "/" + submod.config.storageLocation; };
example = literalExpression ''./. /* <- flake root */ + "/secrets/renced/myhost" /* separate folder for each host */'';
description = ''
The local storage directory for re-encrypted secrets. MUST be a str of path related to flake root.
Expand Down Expand Up @@ -104,21 +104,13 @@ let
'';
};

masterIdentities = mkOption {
identity = mkOption {
type =
with types;
let
identityPathType = coercedTo path toString str;
in
listOf (
# By coercing the old identityPathType into a canonical submodule of the form
# ```
# {
# identity = <identityPath>;
# pubkey = ...;
# }
# ```
# we don't have to worry about it at a later stage.
nullOr (
coercedTo identityPathType
(
p:
Expand All @@ -139,14 +131,11 @@ let
};
})
);
default = [ ];
example = [
./secrets/my-public-yubikey-identity.txt.pub
{
identity = ./password-encrypted-identity.pub;
pubkey = "age1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs3290gq";
}
];
default = null;
example = {
identity = ./password-encrypted-identity.pub;
pubkey = "age1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs3290gq";
};
};

extraRecipients = mkOption {
Expand Down Expand Up @@ -281,7 +270,7 @@ in
serviceConfig = {
Type = "oneshot";
Environment = [
("STORAGE:" + cfg.settings.storageDirStore)
("STORAGE=" + cfg.settings.storageInStore)
checkRencSecsReport
];
ExecStart = "${lib.getExe cfg.package} ${profile} deploy";
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl Profile {
let sec_ciphertext_map: HashMap<profile::Secret, Vec<u8>> =
SecMap::<SecPath<_, InStore>>::from(self.secrets.clone())
.renced(
self.settings.storage_dir_store.clone().into(),
self.settings.storage_in_store.clone().into(),
self.settings.host_pubkey.clone(),
)
.bake_ctx()?
Expand Down
21 changes: 7 additions & 14 deletions src/cmd/renc.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
use eyre::{eyre, ContextCompat, Result};
use eyre::{eyre, Result};
use spdlog::{error, info};
use std::{fs, path::PathBuf};

use crate::helper::stored::Renc;
use crate::interop::add_to_store;
use crate::profile::{MasterIdentity, Profile};
use crate::profile::Profile;

use crate::helper::parse_identity::ParsedIdentity;
impl Profile {
pub fn get_key_pair_iter<'a>(&'a self) -> impl Iterator<Item = Result<ParsedIdentity>> + 'a {
self.settings
.master_identities
.iter()
.map(MasterIdentity::parse)
pub fn get_parsed_ident(&self) -> Result<ParsedIdentity> {
self.settings.identity.parse_from_raw()
}

/**
Expand All @@ -24,7 +21,6 @@ impl Profile {
and add to nix store.
*/
pub fn renc(self, _all: bool, flake_root: PathBuf) -> Result<()> {
let mut key_pair_list = self.get_key_pair_iter();
info!(
"rencrypt for host {}",
self.settings.host_identifier.clone()
Expand All @@ -47,7 +43,7 @@ impl Profile {
// absolute path, in config directory, suffix host ident
let renc_path = {
let mut p = flake_root.clone();
p.push(self.settings.storage_dir_relative.clone());
p.push(self.settings.storage_location.clone());
let p = p.canonicalize()?;
info!(
"reading user identity encrypted dir under flake root: {}",
Expand All @@ -64,11 +60,8 @@ impl Profile {
)
.filter_exist();

let parsed_ident = key_pair_list
.find(|k| k.is_ok())
.wrap_err_with(|| eyre!("available keypair not found"))??;

let key = parsed_ident.get_identity();
let key_pair = self.get_parsed_ident()?;
let key = key_pair.get_identity();

let recip = self.get_host_recip()?;
if let Err(e) = data.map.makeup(vec![recip], &**key) {
Expand Down
17 changes: 9 additions & 8 deletions src/helper/parse_identity.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::profile::MasterIdentity;
use crate::profile::RawIdentity;
use age::{Identity, IdentityFile, Recipient};
use eyre::{eyre, ContextCompat, Result};

Expand All @@ -24,18 +24,19 @@ impl ParsedIdentity {
}
}

impl MasterIdentity {
impl RawIdentity {
// get identiy and recipient from identity file,
// only file that contains info of identity and recip supported at present
// which is expected while using age generated identity
pub fn parse(
Self {
pub fn parse_from_raw(&self) -> Result<ParsedIdentity> {
let Self {
identity,
pubkey: _, // not required. trans from prv key so fast.
}: &Self,
) -> Result<ParsedIdentity> {
pubkey: _, // not required. gen from prv key so fast.
} = self;
if identity.is_empty() {
return Err(eyre!("No identity found"));
return Err(eyre!(
"No identity found, require `vaultix.settings.identity`."
));
} else {
macro_rules! create {
($method:ident, $err_context:expr) => {{
Expand Down
8 changes: 4 additions & 4 deletions src/profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ pub struct Settings {
pub extra_recipients: Vec<String>,
pub host_pubkey: String,
pub host_keys: Vec<HostKey>,
pub storage_dir_relative: String,
pub storage_dir_store: String,
pub master_identities: Vec<MasterIdentity>,
pub storage_location: String,
pub storage_in_store: String,
pub identity: RawIdentity,
}

#[derive(Debug, Deserialize)]
pub struct MasterIdentity {
pub struct RawIdentity {
pub identity: String,
#[allow(dead_code)]
pub pubkey: String,
Expand Down

0 comments on commit 1c187f5

Please sign in to comment.