diff --git a/doc/guides/keys.md b/doc/guides/keys.md index 78bd8ce..b5cf5f7 100644 --- a/doc/guides/keys.md +++ b/doc/guides/keys.md @@ -21,6 +21,29 @@ work well with wire keys include: - [Age](https://github.com/FiloSottile/age) - Anything that non-interactively decrypts to `stdout`. +### Prerequisites + +wire uses a Rust binary to recieve encrypted key data, so your deploying +user must be trusted or you must add garnix as a trusted public key: + +```nix +{ config, ... }: +{ + nix.settings.trusted-users = [ + config.deployment.target.user # [!code ++] + ]; +} +``` + +Otherwise, you may see errors such as: + +``` +error: cannot add path '/nix/store/...-wire-tool-key_agent-x86_64-linux-...' because it lacks a signature by a trusted key +``` + +This is a requirement because `nix copy` is used to copy the binary. +As a benefit to this approach, key deployments are significantly faster! + ### A Trivial "Key" ```nix:line-numbers [hive.nix] diff --git a/doc/guides/non-root-user.md b/doc/guides/non-root-user.md index f846d4f..622adb4 100644 --- a/doc/guides/non-root-user.md +++ b/doc/guides/non-root-user.md @@ -1,7 +1,7 @@ --- comment: true title: Use a non-root user -description: Deploy as any user with wire. +description: Deploy without root permissions with wire. --- # {{ $frontmatter.title }} @@ -13,17 +13,21 @@ description: Deploy as any user with wire. If your selected deployment user does not fit the following requirements, the deployment commands will likely fail with an error: -| | Password-based SSH | Non-interactive SSH Auth | -| :--------------------------------- | -----------------: | -----------------------: | -| In `wheel` (Sudo User) | ❌ Not Supported | ✅ Supported | -| Not In `wheel` (Unprivileged user) | ❌ Not Supported | ❌ Not Supported | +| `deployment.target.user` is... | ❌ Will Not Work | 🟧 Deploys w/o Keys | ✅ Deploys w/ Keys | +| :----------------------------- | :--------------: | :-----------------: | :----------------: | +| In `wheel` (Sudo User) | No | Yes | Yes | +| Has Non-Interactive SSH Auth | - | Yes | Yes | +| A Trusted User | - | No | Yes | + +When using a non-trusted user, `wire apply` will likely fail if the deploying user is +not trusted, see [Manage Secrets - Prerequisites](/guides/keys.html#prerequisites). - "In `wheel`" here meaning a sudoer, whether it be `root` or not. - "Non-interactive SSH Auth" here most likely meaning an SSH key, anything that does not require keyboard input in the terminal. -To put it simply, you cannot have a password on _ssh_, but you can have a -password on _sudo_. +To put it simply, wire can currently prompt for your password on `sudo`, +but not `ssh`. ## Changing the user diff --git a/wire/lib/src/commands/common.rs b/wire/lib/src/commands/common.rs index 3411506..7c576ca 100644 --- a/wire/lib/src/commands/common.rs +++ b/wire/lib/src/commands/common.rs @@ -15,6 +15,16 @@ use crate::{ }, }; +fn get_common_copy_path_help(error: &CommandError) -> Option { + if let CommandError::CommandFailed { logs, .. } = error + && (logs.contains("error: unexpected end-of-file")) + { + Some("wire requires the deploying user or wire binary cache is trusted on the remote server. if you're attempting to make that change, skip keys with --no-keys. please read https://wire.althaea.zone/guides/keys for more information".to_string()) + } else { + None + } +} + pub async fn push(context: &Context<'_>, push: Push<'_>) -> Result<(), HiveLibError> { let command_string = format!( "nix --extra-experimental-features nix-command \ @@ -40,14 +50,20 @@ pub async fn push(context: &Context<'_>, push: Push<'_>) -> Result<(), HiveLibEr ) .await?; - child - .wait_till_success() - .await - .map_err(|error| HiveLibError::NixCopyError { - name: context.name.clone(), - path: push.to_string(), - error: Box::new(error), - })?; + let status = child.wait_till_success().await; + + let help = if let Err(ref error) = status { + get_common_copy_path_help(error).map(Box::new) + } else { + None + }; + + status.map_err(|error| HiveLibError::NixCopyError { + name: context.name.clone(), + path: push.to_string(), + error: Box::new(error), + help, + })?; Ok(()) } diff --git a/wire/lib/src/errors.rs b/wire/lib/src/errors.rs index 9e3b8ff..766855f 100644 --- a/wire/lib/src/errors.rs +++ b/wire/lib/src/errors.rs @@ -336,6 +336,8 @@ pub enum HiveLibError { path: String, #[source] error: Box, + #[help] + help: Option>, }, #[diagnostic(code(wire::Evaluate))]