Skip to content

git githubAuth.nix: the user's PAT as Nix access-tokens, user-level only - #53

Merged
andrewthomaslee merged 1 commit into
mainfrom
nix-access-tokens
Nov 15, 2026
Merged

andrewthomaslee merged 1 commit into
mainfrom
nix-access-tokens

Conversation

@andrewthomaslee

Copy link
Copy Markdown
Member

Summary

New opt-in homeSpec.programs.git.githubAuth.nix.enable: the user's existing github-<user> PAT also authenticates Nix (private github: flake inputs), only in that user's own nix config.

 github-<user>              (clan var, prompted PAT; unchanged)
   ├─ git credential helper, GH_TOKEN, github MCP
+  └─ nix-access-tokens-<user>   (derived clan var, no prompt, dependencies = [github-<user>])
+       script: strip whitespace, require ^(ghp_|github_pat_)[A-Za-z0-9_]+$, else fail
+       file:   access-tokens.conf = "access-tokens = github.com=<pat>"  (owner user, 0400)
+         └─ ~/.config/nix/nix.conf (home-manager nix.extraOptions)
+              !include /run/secrets/vars/.../nix-access-tokens-<user>/access-tokens.conf
  • flake-parts/homeModules/git.nix: githubAuth.nix.{enable,accessTokensFile}, the !include, and an assertion that it needs githubAuth.enabled.
  • flake-parts/nixosModules/git.nix: declares the derived generator for opted-in users and feeds its path in through the existing sharedModules hook, the same way it does patFile.
  • tests/fixtures/nixos.nix: toggle on, so eval-all-enabled covers it.

Why user-level only: if an included line isn't key = value, every nix command fails with syntax error in configuration line. A raw PAT !included into /etc/nix/nix.conf broke the daemon and activation, and the only way back was a GRUB rollback (home history before 887d030). The fetchers run in the client process, so the token never has to reach the system config.

Evidence

Nix 2.34 !include behaviour, tested with fake tokens:

included file result
missing / unreadable silently skipped
access-tokens = github.com=… applied
bare token error: syntax error in configuration line (every nix command)

Generator script with fake inputs: ghp_… and padded github_pat_… → rc 0, nix config show parses the output; oops not a token and empty → rc 1, no file written.

Fixture eval: generators github-alice, nix-access-tokens-alice; alice's nix.extraOptions = !include /run/secrets/vars/nix-access-tokens-alice/access-tokens.conf.

fmt: 0 changed. check (nix run .#flake-check): exit 0. No VM test, as the owner asked (small feature).

Merge Danger

Door: two-way

Off by default; nothing changes until a profile sets githubAuth.nix.enable.

Blast Radius: per-user

When enabled, the worst case (expired or revoked token) breaks only that user's github.com fetches, including public ones. Override for one shell with NIX_CONFIG='access-tokens =' or skip the user config with NIX_USER_CONF_FILES=/dev/null. The daemon, activation and boot never read the file. After rotating github-<user>, regenerate nix-access-tokens-<user> as well.

Merge order: this PR, then home bumps modules and enables the toggle for netsa and matt.

🤖 Generated with Claude Code

homeSpec.programs.git.githubAuth.nix.enable derives a clan var
nix-access-tokens-<user> from the existing github-<user> PAT (no new
prompt) and !includes it from the user's ~/.config/nix/nix.conf, so nix
can fetch private github: inputs. The system nix.conf is never touched:
an included line that is not `key = value` is a hard syntax error for
every nix command, which in /etc/nix/nix.conf took down the daemon and
activation and needed a GRUB rollback. The generator validates the token
shape so a bad value fails at `clan vars generate`, and !include skips
a missing or unreadable file before the var is deployed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andrewthomaslee
andrewthomaslee enabled auto-merge (squash) November 15, 2026 00:34
@andrewthomaslee
andrewthomaslee merged commit 6107139 into main Nov 15, 2026
3 checks passed
andrewthomaslee added a commit to external-systems/home that referenced this pull request Nov 15, 2026
## Summary

Bumps `modules` to external-systems/modules#53 (merged) and turns on
`githubAuth.nix` for netsa and matt. Nix fetches private `github:`
inputs with the user's existing `github-<user>` PAT, and only that
user's own nix config ever sees it.

```diff
 users/netsa/default.nix, users/matt/default.nix
-  githubAuth.enabled = true;
+  githubAuth = {
+    enabled = true;
+    nix.enable = true;   # ~/.config/nix/nix.conf: !include <nix-access-tokens-<user>>
+  };
 vars/shared/
+  nix-access-tokens-netsa/   (beelink, ghost, kamrui-h1, nixos)
+  nix-access-tokens-matt/    (beelink)
 documentation/docs/fleet/github-token-rotation.md
+  where nix gets the token; the runbook regenerates nix-access-tokens-<user> too
```

The vars were generated on this branch (`clan vars generate beelink`;
the vars are shared, so both users are covered). There were no new
prompts: each var is derived from `github-<user>/pat`.

## Evidence

- **Before:** outside devenv, nix has no GitHub token, so private inputs
(`secrets`) 404.
**After:** kamrui-h1's netsa home-manager `nix.extraOptions` evaluates
to `!include <deployed nix-access-tokens-netsa path>` (before generation
it was `!include /no-such-path`, which Nix skips).
- Each generator checks the token shape (`^(ghp_|github_pat_)…`) and
both PATs passed. A malformed token would have failed `clan vars
generate`.
- `clan vars check`: "All vars are present and valid" for beelink,
euc-hel-0, ghost, hp-notebook, kamrui-h1 and nixos.
- `fmt`: 0 changed. `check`: exit 0.

## Merge Danger

**Door:** two-way

The system `/etc/nix/nix.conf` is unchanged, so the daemon, activation
and boot never read the token. Roll back by turning off `nix.enable`.

**Blast Radius:** per-user

If the token is revoked, only that user's github.com fetches fail.
Override for one shell with `NIX_CONFIG='access-tokens ='`. Takes effect
on each machine at its next deploy (kamrui-h1, beelink, ghost, nixos).

Merge order: modules#53 (merged), then this PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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

Successfully merging this pull request may close these issues.

1 participant