Skip to content

Commit 33a9514

Browse files
committed
feat: store access tokens in access-tokens.conf
Instead of updating the nix.conf file constantly, store the tokens in a separate file, and use the !include feature to load it from the main config file. If access-tokens exist in nix.conf, the tool will automatically migrate them to the separate access-tokens.conf file. That will reduce the number of backups we have to do. Plus it allows the main config file to retain 0644 mode while keeping the access-tokens locked down further.
1 parent 0e34f66 commit 33a9514

File tree

13 files changed

+1234
-512
lines changed

13 files changed

+1234
-512
lines changed

README.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ to get those tokens in the right place.
1010

1111
- OAuth device flow authentication when possible (no manual token creation needed)
1212
- Support for multiple providers (GitHub, GitHub Enterprise, GitLab, Gitea, and Forgejo)
13-
- Token storage in `~/.config/nix/nix.conf`
13+
- Secure token storage in separate `~/.config/nix/access-tokens.conf` file with restricted permissions
1414
- Token validation and status checking
1515
- Automatic backup creation before modifying configuration
1616

@@ -86,7 +86,7 @@ The tool will:
8686
1. Display a one-time code
8787
2. Open your browser to the provider's device authorization page
8888
3. Wait for you to authorize the application
89-
4. Save the token to `~/.config/nix/nix.conf`
89+
4. Save the token to `~/.config/nix/access-tokens.conf` (with restricted 0600 permissions)
9090

9191
**Note for self-hosted instances**:
9292
- **GitHub Enterprise**: You'll need to create an OAuth App and provide the client ID via `--client-id`
@@ -132,17 +132,26 @@ nix-auth logout --host github.company.com
132132

133133
## How It Works
134134

135-
The tool manages the `access-tokens` configuration in your `~/.config/nix/nix.conf` file. This allows Nix to authenticate when fetching flake inputs from private repositories or builtins fetchers, and hitting rate limits.
135+
The tool manages access tokens in a secure, separate configuration file that is included by your main Nix configuration. This allows Nix to authenticate when fetching flake inputs from private repositories or builtins fetchers, and avoiding rate limits.
136136

137-
Example configuration added by this tool:
138-
```
139-
access-tokens = github.com=ghp_xxxxxxxxxxxxxxxxxxxx gitlab.com=glpat-xxxxxxxxxxxx github.company.com=ghp_yyyyyyyy
140-
```
137+
The tool automatically:
138+
1. Creates `~/.config/nix/access-tokens.conf` with restricted permissions (0600)
139+
2. Adds an include directive to your `~/.config/nix/nix.conf`:
140+
```
141+
!include access-tokens.conf
142+
```
143+
3. Stores tokens in the secure file:
144+
```
145+
access-tokens = github.com=ghp_xxxxxxxxxxxxxxxxxxxx gitlab.com=glpat-xxxxxxxxxxxx
146+
```
147+
148+
This separation ensures your tokens are stored with proper security permissions while keeping your main configuration readable.
141149

142150
## Security
143151

144-
- Tokens are stored locally in your Nix configuration
152+
- Tokens are stored in a separate file (`access-tokens.conf`) with restricted permissions (0600)
145153
- The tool creates automatic backups before modifying your configuration
154+
- Automatically migrates existing tokens from `nix.conf` to the secure token file
146155
- Uses OAuth device flow for secure authentication
147156
- Minimal required permissions (only necessary scopes for accessing repositories)
148157

cmd/login.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"fmt"
88
"strings"
99

10-
"github.com/numtide/nix-auth/internal/config"
10+
"github.com/numtide/nix-auth/internal/nixconf"
1111
"github.com/numtide/nix-auth/internal/provider"
1212
"github.com/numtide/nix-auth/internal/ui"
1313
"github.com/spf13/cobra"
@@ -94,7 +94,7 @@ func runLogin(_ *cobra.Command, args []string) error {
9494
}
9595

9696
// Check if token already exists
97-
cfg, err := config.New(configPath)
97+
cfg, err := nixconf.New(configPath)
9898
if err != nil {
9999
return fmt.Errorf("failed to initialize config: %w", err)
100100
}

cmd/logout.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"strconv"
66
"strings"
77

8-
"github.com/numtide/nix-auth/internal/config"
8+
"github.com/numtide/nix-auth/internal/nixconf"
99
"github.com/numtide/nix-auth/internal/provider"
1010
"github.com/numtide/nix-auth/internal/ui"
1111
"github.com/spf13/cobra"
@@ -25,7 +25,7 @@ You can specify either a provider name (github, gitlab) or a full host.`,
2525
}
2626

2727
func runLogout(_ *cobra.Command, args []string) error {
28-
cfg, err := config.New(configPath)
28+
cfg, err := nixconf.New(configPath)
2929
if err != nil {
3030
return fmt.Errorf("failed to initialize config: %w", err)
3131
}
@@ -48,7 +48,7 @@ func runLogout(_ *cobra.Command, args []string) error {
4848
}
4949

5050
// logoutInteractive handles the interactive logout flow.
51-
func logoutInteractive(cfg *config.NixConfig) error {
51+
func logoutInteractive(cfg *nixconf.NixConfig) error {
5252
hosts, err := cfg.ListTokens()
5353
if err != nil {
5454
return fmt.Errorf("failed to list tokens: %w", err)
@@ -84,7 +84,7 @@ func logoutInteractive(cfg *config.NixConfig) error {
8484
return removeToken(cfg, hosts[choice-1])
8585
}
8686

87-
func removeToken(cfg *config.NixConfig, host string) error {
87+
func removeToken(cfg *nixconf.NixConfig, host string) error {
8888
fmt.Printf("Removing token for %s...\n", host)
8989

9090
if err := cfg.RemoveToken(host); err != nil {

cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package cmd
33
import (
44
"fmt"
55

6-
"github.com/numtide/nix-auth/internal/config"
6+
"github.com/numtide/nix-auth/internal/nixconf"
77
"github.com/spf13/cobra"
88
)
99

@@ -25,7 +25,7 @@ func Execute() error {
2525

2626
func init() {
2727
// Add persistent flag for config path
28-
defaultPath := config.DefaultUserConfigPath()
28+
defaultPath := nixconf.DefaultUserConfigPath()
2929
flagDesc := fmt.Sprintf("Path to nix.conf file (default: %s)", defaultPath)
3030
rootCmd.PersistentFlags().StringVar(&configPath, "config", "", flagDesc)
3131

cmd/set_token.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"context"
55
"fmt"
66

7-
"github.com/numtide/nix-auth/internal/config"
7+
"github.com/numtide/nix-auth/internal/nixconf"
88
"github.com/numtide/nix-auth/internal/provider"
99
"github.com/numtide/nix-auth/internal/ui"
1010
"github.com/spf13/cobra"
@@ -44,7 +44,7 @@ If a provider is specified or detected, the token will be validated before savin
4444
host := args[0]
4545

4646
// Initialize config
47-
cfg, err := config.New(configPath)
47+
cfg, err := nixconf.New(configPath)
4848
if err != nil {
4949
return fmt.Errorf("failed to initialize config: %w", err)
5050
}
@@ -139,7 +139,7 @@ If a provider is specified or detected, the token will be validated before savin
139139

140140
maskedToken := ui.MaskToken(token)
141141
fmt.Printf("Successfully set token for %s: %s\n", host, maskedToken)
142-
fmt.Printf("Config saved to: %s\n", cfg.GetPath())
142+
fmt.Printf("Config saved to: %s\n", cfg.GetTokenFilePath())
143143

144144
return nil
145145
},

0 commit comments

Comments
 (0)