Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for identities on yubikeys #115

Open
antifuchs opened this issue Jun 5, 2022 · 3 comments
Open

Better support for identities on yubikeys #115

antifuchs opened this issue Jun 5, 2022 · 3 comments

Comments

@antifuchs
Copy link

antifuchs commented Jun 5, 2022

I was trying to use age-plugin-yubikey with rage to create a key that doesn't live on my file system. This works, but not completely conveniently all the way: agenix happily encrypts to the identity on my yubikey, but then fails to decrypt when editing the existing secret unless you create an "identity" file containing the handle that lives on the yubikey.

I'm opening this (effectively non-)issue to help others along who are trying to use yubikeys with agenix.

Guide

You'll need:

  • The identity of the generated private key, retrieved via age-plugin-yubikey --identity. It looks like AGE-PLUGIN-YUBIKEY-3XXXXXXXXXX3XX3XXXXXX
  • The public key for that identity, retrieved via age-plugin-yubikey --list. It looks like age1yubikey1q0m3cprmex0d2thamkx9pwvhsqwcm2gel50rdxmeclvkgqtem9dxz4smpwv.

Here's an example secrets.nix:

let
  machines = {
    monitor = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINmveI8P/aqICzkZ+2nTxbV7RB5/ZEsgsxZmC3IajYxL root@ubuntu-s-1vcpu-1gb-nyc3-01"; # A normal SSH ed25519 key.
  };

  users = {
    personal-4c = "age1yubikey1q0m3cprmex0d2thamkx9pwvhsqwcm2gel50rdxmeclvkgqtem9dxz4smpwv"; # the public key
  };
in
{
  "test.age".publicKeys = [ users.personal-4c machines.monitor ];
}

Then, write the identity to a file in your secrets folder. I named it secrets/identities/personal-4c.txt:

$ mkdir -p identities && echo AGE-PLUGIN-YUBIKEY-3XXXXXXXXXX3XX3XXXXXX > identities/personal-4c.txt

Then, you can edit the secret like so:

$ agenix -e test.age --identity identities/personal-4c.txt

As explained in str4d/age-plugin-yubikey#73, these yubikey identities are "key grips", encoding a serial number of the yubikey and some other identifiers, but no secret bits. It's fine to store them in the repo, but here's the ask I have for agenix: Would it be possible to use age-plugin-yubikey --list-all or --identity to retrieve any connected identities, if they correspond to any public keys that are connected to the machine, so that we don't have to explicitly pass the --identity flag?

@kolpav
Copy link

kolpav commented Dec 17, 2022

Just to make sure in the permutation tesseract of how to easily manage secrets in nixos project where columns would be something like

| rage/age/agenix/sops-nix | flake |gpg/[open]ssh/ssh-to-gpg | yubikey + piv | pgp | fido2 | otp | ecdsa | ecdsask | ed25519 | ed25519sk

I am row agenix, flake, ssh, yubikey, fido2, sk-ssh-ed25519 which is not supported right?

~ nix run github:ryantm/agenix -- -e test.age --identity secrets/identities/personal-4c.txt
Error: Unsupported SSH key: ⁨⁩

Unsupported SSH Key Type
------------------------
OpenSSH supports various different key types, but rage only supports a
subset of these for backwards compatibility, specifically the 'ssh-rsa'
and 'ssh-ed25519' key types. This SSH key uses the unsupported key type
'⁨sk-ssh-ed25519⁩'.

Are there more pages (nix wiki, all projects I mentioned, yubikey docs) I need to read or tools to install to make this work or I am out of luck?

supermarin added a commit to supermarin/dotfiles that referenced this issue Jul 6, 2023
Cache key grip to see if PIN prompting reduces.

From ryantm/agenix#115 (comment):
> As explained in github.com/str4d/age-plugin-yubikey#73, these yubikey
> identities are "key grips", encoding a serial number of the yubikey and
> some other identifiers, but no secret bits.
@dghubble
Copy link

dghubble commented Jan 14, 2024

Like the OP, I used an age public key and noticed the identity file has to be passed on every invocation of agenix. Maybe it would be better if we could add something like the module's identityPaths, but to the secrets.nix file. A way to tell agenix to always consider a particular identity without having to set it on the command line. Right now the rules parser isn't really setup for this, but it might look like:

# hypothetical syntax
let
  myself = "age1yubikey...";
in
{
  "foo.age".publicKeys = [ myself ];
  identityPaths = [ "../identity.txt" ];
}

@TRPB
Copy link

TRPB commented Nov 17, 2024

Thanks for this. I must be missing something here.

I've set up my identity and encrypted I've added my key using ssh-add -K to load the key, configured the public key using the age1yubikey... value and I can successfully decrypt and re-encrypt the age file using agenix -e test.age --identity identities/yubikey1.txt

But, when I nixos-rebuild switch I get no identity matched any of the recipient. Do I need to somehow pass the identity at this stage as well?

edit: RTFM, I need to set `age.identityPaths = [ "/path/to/yubikey1.txt" ]

But, when I do that I get:

age: error: yubikey plugin: couldn't start plugin: age-plugin-yubikey resolves to executable in current directory

I have age-plugin-yubikey installed via envrionment.systemPackages so I don't understand what this error means

resolved by this post: https://discourse.nixos.org/t/agenix-ragenix-issues-with-age-plugin-yubikey-and-the-mysterious-age-plugin-yubikey-resolves-to-executable-in-current-directory-error/46890

But now I'm getting A PIN is required for YubiKey with serial

agenix is asking for the pin but I can't enter it

so... if I:

  1. agenix -e test.age --identity identities/yubikey1.txt
  2. Enter the pin and press the yubikey
  3. Leave the edtior open
  4. nixos-rebuild switch

It builds successfully and the secret is available.

I checked the pin policy and it's set to once:

PIN policy: Once   (A PIN is required once per session, if set)

It seems to be that nixos-rebuild doesn't support being dropped to user input to allow entering the pin

edit: And the answer to that one is to make sure you use age, not rage:

  age.ageBin = "PATH=$PATH:${lib.makeBinPath [ pkgs.age-plugin-yubikey ]} ${pkgs.age}/bin/age";

it asks for the pin and waits for the yubikey to be pressed when running nixos-rebuild switch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants