iTranslated by AI
Managing GitHub Tokens on NixOS with agenix for HTTPS Git Authentication
This article is a record of the steps to configure HTTPS Git authentication on NixOS using
agenixand a GitHub Fine-grained personal access token (hereinafter referred to as "token"), while manually editing.nixfiles without using flakes.
I will organize how to handle tokens when running NixOS on UTM and wanting to clone / pull / push GitHub repositories from the NixOS side.
In this guide, we will assume a configuration that uses a token instead of an SSH key, summarizing the process of managing the token with encryption using agenix and utilizing it for operations like git clone.
Prerequisites
- NixOS is already running
- You can log in to NixOS via external SSH
- Token has already been issued
- Git remote uses HTTPS
1. Add agenix module to /etc/nixos/configuration.nix
First, we make the agenix module accessible. Here, we define the source for agenix using let ... in near the beginning of configuration.nix.
let
agenixSrc = builtins.fetchTarball "https://github.com/ryantm/agenix/archive/main.tar.gz";
in
Add the following to imports.
imports = [
./hardware-configuration.nix
"${agenixSrc}/modules/age.nix"
];
Add the following to environment.systemPackages.
environment.systemPackages = with pkgs; [
git
vim
curl
wget
age
ssh-to-age
];
Apply the changes.
sudo nixos-rebuild switch
2. Enable the agenix CLI
Next, we make the agenix command itself usable. Here, we also add the CLI to environment.systemPackages.
environment.systemPackages = with pkgs; [
git
vim
curl
wget
age
ssh-to-age
(pkgs.callPackage "${agenixSrc}/pkgs/agenix.nix" {})
];
Apply again.
sudo nixos-rebuild switch
Verification:
which agenix
agenix --help
3. Create /etc/nixos/secrets/secrets.nix
We use the host public key on the NixOS side for decryption. In this case, we use this host key so that NixOS itself can decrypt the secret.
First, check the public key.
sudo cat /etc/ssh/ssh_host_ed25519_key.pub
After that, create /etc/nixos/secrets/secrets.nix.
sudo mkdir -p /etc/nixos/secrets
sudo nano /etc/nixos/secrets/secrets.nix
The content should be as follows:
let
nixosHost = "ssh-ed25519 AAAA..... root@hostname";
in
{
"github-token.age".publicKeys = [ nixosHost ];
}
Please replace AAAA..... with the full public key string you verified earlier.
4. Encrypt the token
Next, create an encrypted secret file to store the token.
cd /etc/nixos/secrets
sudo EDITOR=nano agenix -e github-token.age
Paste the token into the editor that opens and save it.
This will generate github-token.age.
5. Add decryption configuration to configuration.nix
Next, configure the encrypted token to be decrypted and usable after NixOS boots.
Add the following to /etc/nixos/configuration.nix:
age.secrets.github-token = {
file = /etc/nixos/secrets/github-token.age;
owner = "username";
group = "users";
mode = "0400";
};
Replace username with the user name that will actually use Git. Since we named the secret github-token, it will be referenced as /run/agenix/github-token after decryption.
Apply the changes.
sudo nixos-rebuild switch
6. Verify the decrypted token
In this configuration, the decrypted file will be placed at /run/agenix/github-token.
ls -l /run/agenix
ls -l /run/agenix/github-token
With this configuration, since owner = "username" and mode = "0400" are set, the user themselves can read it, but other regular users cannot.
7. Configure Git to reference the token
Make the Git credential helper read from /run/agenix/github-token. In this case, for HTTPS authentication to GitHub, we return the contents of this file as the password. We also return the username here.
git config --global credential.https://github.com.username <github-user-name>
git config --global credential.helper '!f() { echo username=<github-user-name>; echo password=$(cat /run/agenix/github-token); }; f'
8. Test git clone
git clone https://github.com/<github-user-name>/<repo-name>.git
This allows you to perform clone / pull / push using the token managed with encryption.
Supplemental information
In this configuration, the token is stored encrypted as an .age file.
However, when Git actually uses it, it is placed in a decrypted state at /run/agenix/github-token.
However, because we set the permissions to 0400 and limited the owner to the Git-executing user, it can be kept in a state where other users cannot access it.
Also, the user executing Git can read /run/agenix/github-token.
This is because that user needs the token for GitHub authentication, which is the intended behavior in this configuration.
When using different tokens for each repository
If you want to use different GitHub Fine-grained personal access tokens for each repository, it is easier to understand if you manage the secrets separately with agenix as well.
For example:
repo-a-token.agerepo-b-token.age
Define them individually in configuration.nix as well.
age.secrets.repo-a-token = {
file = /etc/nixos/secrets/repo-a-token.age;
owner = "username";
group = "users";
mode = "0400";
};
age.secrets.repo-b-token = {
file = /etc/nixos/secrets/repo-b-token.age;
owner = "username";
group = "users";
mode = "0400";
};
In this case, it is easier to handle the Git credential helper using local settings for each repository instead of --global.
For example, in the repo-a directory:
git config --local credential.https://github.com.username <github-user-name>
git config --local credential.helper '!f() { echo username=<github-user-name>; echo password=$(cat /run/agenix/repo-a-token); }; f'
In repo-b:
git config --local credential.https://github.com.username <github-user-name>
git config --local credential.helper '!f() { echo username=<github-user-name>; echo password=$(cat /run/agenix/repo-b-token); }; f'
By doing this, you can easily use different tokens for different repositories.
Conclusion
When handling tokens on NixOS, by using agenix, you can manage them without writing them directly into configuration files in plain text.
The initial setup is a bit of work, but:
- Can be stored encrypted
- Easy to manage as part of the NixOS configuration
- Permissions can be restricted to only the Git-using user
- Tokens can be separated per repository if necessary
In these respects, it was an easier configuration to organize for managing tokens on NixOS compared to handling them directly in plain text.
Discussion