Skip to content

Commit 8112224

Browse files
committed
document mise-first workflow and architecture diagrams
1 parent 5066971 commit 8112224

41 files changed

Lines changed: 4724 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.local.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(mkdir:*)",
5+
"Bash(tree:*)",
6+
"Bash(chmod:*)",
7+
"Bash(cat:*)",
8+
"Bash(ls:*)",
9+
"Bash(grep:*)"
10+
]
11+
}
12+
}

.github/dependabot.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Dependabot configuration for NixOS repository
2+
# Automatically checks for dependency updates and creates PRs
3+
4+
version: 2
5+
updates:
6+
# GitHub Actions - Keep workflow actions up to date
7+
- package-ecosystem: "github-actions"
8+
directory: "/"
9+
schedule:
10+
interval: "weekly"
11+
day: "monday"
12+
time: "09:00"
13+
timezone: "UTC"
14+
labels:
15+
- "dependencies"
16+
- "github-actions"
17+
commit-message:
18+
prefix: "ci"
19+
include: "scope"
20+
# Group all GitHub Actions updates into a single PR
21+
groups:
22+
github-actions:
23+
patterns:
24+
- "*"
25+
open-pull-requests-limit: 5
26+
reviewers:
27+
- "giovanni" # Replace with your GitHub username
28+
# Ignore major version updates for critical actions
29+
ignore:
30+
- dependency-name: "actions/*"
31+
update-types: ["version-update:semver-major"]
32+
33+
# Note: Nix flake dependencies are typically managed manually with:
34+
# just update
35+
# git commit -am "update: flake inputs"
36+
# just deploy-all
37+
#
38+
# Dependabot doesn't natively support Nix flakes yet.
39+
# For automated flake updates, consider using:
40+
# - GitHub Actions workflow with scheduled `nix flake update`
41+
# - renovatebot with Nix support

.github/instructions.md

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# GitHub Copilot Instructions
2+
3+
This NixOS configuration repository uses **categorized hosts** with automated zero-touch installation. All commands use `justfile`.
4+
5+
## Quick Reference
6+
7+
### Essential Commands
8+
9+
```bash
10+
just --list # List all commands
11+
just install <host> <cat> <ip> # Install new host (fully automated)
12+
just deploy <hostname> # Deploy configuration
13+
just deploy-all # Deploy to all hosts
14+
just check # Validate flake
15+
just fmt # Format Nix files
16+
just update # Update flake inputs
17+
just secrets # Edit encrypted secrets
18+
just knock <vps> # Port knock and SSH to VPS
19+
```
20+
21+
### Repository Structure
22+
23+
```
24+
flake.nix # Main flake, defines all hosts
25+
justfile # All commands (replaces Make/scripts)
26+
hosts/
27+
categories/ # Category-specific configs
28+
laptops.nix # Full workstations
29+
vps.nix # Hardened cloud instances
30+
servers.nix # On-premises servers
31+
experiments.nix # Development/testing
32+
{category}/{hostname}/ # Individual host configs
33+
modules/
34+
networking/ # Tailscale, firewall, port knocking
35+
system/ # Security modules
36+
users/ # Home Manager configs
37+
secrets/ # SOPS-encrypted secrets
38+
```
39+
40+
## Host Categories
41+
42+
- **laptops** (bit, spark, hermes): Full workstation with desktop, dev tools, Docker
43+
- **vps** (vps-alpha, ...): Hardened minimal cloud with port knocking, auto-updates
44+
- **servers** (server-alpha, ...): On-premises with Docker, monitoring
45+
- **experiments** (test-vm, ...): Development with relaxed security
46+
47+
## Adding a New Host
48+
49+
**Automated (recommended):**
50+
```bash
51+
# Boot NixOS installer on target, then:
52+
just install spark laptops 192.168.1.100
53+
# Wait ~15 min - completely hands-off
54+
```
55+
56+
**Manual:**
57+
1. Create `hosts/{category}/{hostname}/configuration.nix`
58+
2. Add to `flake.nix` nixosConfigurations using `mkHost`
59+
3. Add to `deploy.nodes` for remote deployment
60+
61+
## Security Rules
62+
63+
1. **Never hardcode secrets** - use SOPS encryption
64+
2. **All secrets via `just secrets`** - edit `secrets/common/secrets.yaml`
65+
3. **Port knocking for VPS** - sequences in `secrets/vps/knock-sequences.yaml`
66+
4. **Tailscale for all hosts** - use hostnames, not IPs
67+
5. **SSH key-only auth** - no passwords
68+
6. **Run `just check` before commit** - validates all configs
69+
7. **Format with `just fmt`** - before committing Nix files
70+
71+
## Secrets Management
72+
73+
```bash
74+
just secrets # Edit common secrets
75+
just secrets secrets/vps/knock-sequences.yaml # Edit VPS secrets
76+
just secrets-view <file> # View decrypted
77+
just secrets-update # Re-encrypt after adding host
78+
```
79+
80+
**All secrets encrypted with SOPS (GPG + age). Never commit unencrypted secrets.**
81+
82+
## Common Patterns
83+
84+
### Deploying Changes
85+
86+
```bash
87+
vim hosts/laptops/spark/configuration.nix
88+
just deploy spark
89+
```
90+
91+
### Updating All Hosts
92+
93+
```bash
94+
just update # Update flake inputs
95+
git commit -am "update flake"
96+
just deploy-all # Deploy everywhere
97+
```
98+
99+
### VPS Access (Port Knocking)
100+
101+
```bash
102+
just knock vps-alpha # Knocks and opens SSH
103+
```
104+
105+
### Rollback
106+
107+
```bash
108+
just rollback spark # Rollback to previous generation
109+
just generations spark # List all generations
110+
```
111+
112+
## Module Organization
113+
114+
- **Common modules** in `hosts/common/default.nix` - affect ALL hosts
115+
- **Category configs** in `hosts/categories/` - affect all hosts in category
116+
- **Host configs** in `hosts/{category}/{hostname}/` - host-specific only
117+
- **Network modules** in `modules/networking/` - Tailscale, firewall, knockd
118+
- **User modules** in `modules/users/` - Home Manager configurations
119+
120+
## Best Practices
121+
122+
1. **Use category configs** for shared functionality within a category
123+
2. **Test with dry-run** before deploying: `just dry-run spark`
124+
3. **Validate before commit**: `just check && just fmt`
125+
4. **Use Tailscale names** for addressing (opaque, no IPs in code)
126+
5. **Per-host hardware-configuration.nix** is auto-generated
127+
6. **Category changes affect all hosts** in that category - test carefully
128+
7. **Common changes affect ALL hosts** - be extremely conservative
129+
8. **VPS hardening is intentional** - minimal packages, port knocking, kernel hardening
130+
131+
## Troubleshooting
132+
133+
```bash
134+
just check # Validate flake syntax
135+
just dry-run <host> # See what would change
136+
just rollback <host> # Rollback to previous generation
137+
just tailscale-status <host> # Check Tailscale connection
138+
just info <host> # System information
139+
ssh <host> 'journalctl -xe' # View system logs
140+
```
141+
142+
## Development Workflow
143+
144+
```bash
145+
nix develop # Enter dev shell (has all tools)
146+
just check # Validate all configs
147+
just fmt # Format all Nix files
148+
just build <host> # Build without deploying
149+
```
150+
151+
## Documentation
152+
153+
- `AGENTS.md` - Complete AI assistant reference
154+
- `docs/WORKFLOW.md` - Installation and deployment workflow
155+
- `docs/JUSTFILE_COMMANDS.md` - Full command reference
156+
- `docs/SOPS_GPG_SETUP.md` - Secrets management guide
157+
- `README.md` - Main repository documentation
158+
159+
## Automated Installation Features
160+
161+
The `just install` command does everything automatically:
162+
1. Generates age encryption key
163+
2. Partitions/formats disk
164+
3. Installs NixOS
165+
4. Deploys age key
166+
5. Fetches hardware config
167+
6. Creates host configuration
168+
7. Updates .sops.yaml
169+
8. Updates flake.nix
170+
9. Re-encrypts secrets
171+
10. Commits to git
172+
11. Deploys full config
173+
174+
**Result: Fully configured system in ~15 minutes with zero manual steps.**
175+
176+
## Key Files
177+
178+
- `flake.nix` - Host definitions, uses `mkHost` helper
179+
- `justfile` - All commands (install, deploy, secrets, etc.)
180+
- `.sops.yaml` - SOPS encryption configuration (GPG + age keys)
181+
- `hosts/common/default.nix` - Shared config for ALL hosts
182+
- `hosts/categories/{category}.nix` - Category-specific configs
183+
- `secrets/common/secrets.yaml` - Encrypted common secrets (Tailscale authkey, etc.)
184+
- `secrets/vps/knock-sequences.yaml` - Encrypted port knock sequences
185+
186+
## When Suggesting Code
187+
188+
- Use `just` commands, not scripts or make
189+
- Respect host categories and their security levels
190+
- Never suggest hardcoding secrets
191+
- Always validate with `just check`
192+
- Format with `just fmt`
193+
- Test with `just dry-run` before deploying
194+
- Use Tailscale hostnames, not IPs
195+
- Maintain zero-touch installation automation
196+
- Follow DRY principle with `mkHost` helper
197+
- Keep VPS configs minimal and hardened

.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Nix build outputs
2+
result
3+
result-*
4+
5+
# Hardware configuration (machine-specific)
6+
# Uncomment if you want to ignore hardware configs
7+
# hosts/*/hardware-configuration.nix
8+
9+
# Secrets - DO NOT COMMIT
10+
secrets/
11+
*.age
12+
*.key
13+
!*.pub
14+
15+
# IDE
16+
.vscode/
17+
.idea/
18+
*.swp
19+
*.swo
20+
*~
21+
22+
# macOS
23+
.DS_Store
24+
25+
# Development
26+
.direnv/
27+
.envrc

.secrets.baseline

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
{
2+
"version": "1.4.0",
3+
"plugins_used": [
4+
{
5+
"name": "ArtifactoryDetector"
6+
},
7+
{
8+
"name": "AWSKeyDetector"
9+
},
10+
{
11+
"name": "Base64HighEntropyString",
12+
"limit": 4.5
13+
},
14+
{
15+
"name": "BasicAuthDetector"
16+
},
17+
{
18+
"name": "CloudantDetector"
19+
},
20+
{
21+
"name": "HexHighEntropyString",
22+
"limit": 3.0
23+
},
24+
{
25+
"name": "IbmCloudIamDetector"
26+
},
27+
{
28+
"name": "IbmCosHmacDetector"
29+
},
30+
{
31+
"name": "JwtTokenDetector"
32+
},
33+
{
34+
"name": "KeywordDetector",
35+
"keyword_exclude": ""
36+
},
37+
{
38+
"name": "MailchimpDetector"
39+
},
40+
{
41+
"name": "PrivateKeyDetector"
42+
},
43+
{
44+
"name": "SlackDetector"
45+
},
46+
{
47+
"name": "SoftlayerDetector"
48+
},
49+
{
50+
"name": "StripeDetector"
51+
},
52+
{
53+
"name": "TwilioKeyDetector"
54+
}
55+
],
56+
"filters_used": [
57+
{
58+
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
59+
},
60+
{
61+
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
62+
"min_level": 2
63+
},
64+
{
65+
"path": "detect_secrets.filters.heuristic.is_indirect_reference"
66+
},
67+
{
68+
"path": "detect_secrets.filters.heuristic.is_likely_id_string"
69+
},
70+
{
71+
"path": "detect_secrets.filters.heuristic.is_potential_uuid"
72+
},
73+
{
74+
"path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
75+
},
76+
{
77+
"path": "detect_secrets.filters.heuristic.is_sequential_string"
78+
},
79+
{
80+
"path": "detect_secrets.filters.heuristic.is_templated_secret"
81+
}
82+
],
83+
"results": {},
84+
"generated_at": "2025-12-15T00:00:00Z"
85+
}

0 commit comments

Comments
 (0)