|
| 1 | +# authd Development Environment |
| 2 | + |
| 3 | +LXD VM for daily authd development. Provides full systemd, D-Bus, SSH, and GDM — |
| 4 | +enough to build, test, and exercise real PAM/NSS login flows without touching your |
| 5 | +host system. The host source tree is bind-mounted at `/workspace/authd`. |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +- LXD: `sudo snap install lxd && lxd init --auto && sudo usermod -aG lxd "$USER"` (logout/login) |
| 10 | +- SSH key: `ls ~/.ssh/id_ed25519.pub || ssh-keygen -t ed25519` |
| 11 | +- SPICE viewer (only needed for `lxc console --type=vga`): `sudo apt install virt-viewer` |
| 12 | + |
| 13 | +The SSH key is injected into the VM for key-based authentication, VS Code Remote SSH, |
| 14 | +and testing PAM login flows over SSH (`ssh user@domain.com@vm-ip`). |
| 15 | + |
| 16 | +## Quick Start |
| 17 | + |
| 18 | +```bash |
| 19 | +./dev/dev-env.sh up # Create VM + build authd (~20 min first time) |
| 20 | +./dev/dev-env.sh broker google \ |
| 21 | + --client-id ID --client-secret SEC \ |
| 22 | + --ssh-suffixes '@gmail.com' # Configure broker |
| 23 | +ssh you@gmail.com@$(./dev/dev-env.sh ip) # Test login from host |
| 24 | +``` |
| 25 | + |
| 26 | +The `up` command provisions the VM, installs all toolchains (Go, Rust, protoc), |
| 27 | +and automatically builds + installs authd, PAM, and NSS modules. After `up` |
| 28 | +completes, the only manual step is configuring a broker with your IdP credentials. |
| 29 | + |
| 30 | +## Commands |
| 31 | + |
| 32 | +Global flags (before the subcommand, apply to all commands): |
| 33 | +`--name NAME` (default: authd-dev), `--release NAME` (default: noble), `--workspace PATH` (default: /workspace/authd). |
| 34 | + |
| 35 | +| Command | Description | |
| 36 | +|---------|-------------| |
| 37 | +| `up` | Create and provision VM (also restarts a stopped VM) | |
| 38 | +| `stop` | Stop VM (preserves state; restart with `up`) | |
| 39 | +| `down [--force]` | Stop and delete VM and profile | |
| 40 | +| `shell` | Direct shell via `lxc exec` (no PAM, always works) | |
| 41 | +| `ssh` | Connect via SSH (goes through PAM — for login testing) | |
| 42 | +| `status` | VM status and snapshots | |
| 43 | +| `snapshot <name>` / `restore <name>` | Manage snapshots | |
| 44 | +| `broker <variant> [opts]` | Configure credentials + install broker; `--rebuild` to recompile without touching credentials; `edit` subaction to open broker.conf | |
| 45 | +| `build [component]` | Fast rebuild + install a single component | |
| 46 | +| `validate` | Health-check authd stack (socket, PAM, NSS, brokers) | |
| 47 | +| `test [args]` | Run tests inside the VM (e.g. `--update-golden`, `--skip-external`) | |
| 48 | +| `logs [target]` | Tail logs (authd/google/msentraid/oidc/cloud-init) | |
| 49 | +| `exec <cmd>` | Run a command inside the VM (in workspace dir) | |
| 50 | +| `ip` | Print VM IP | |
| 51 | + |
| 52 | +## Iterative Development |
| 53 | + |
| 54 | +After the initial `install-authd`, use `build` from the **host**: |
| 55 | + |
| 56 | +```bash |
| 57 | +./dev/dev-env.sh build authd # Daemon + proto regen + restart |
| 58 | +./dev/dev-env.sh build pam # PAM modules (reconnect SSH to load) |
| 59 | +./dev/dev-env.sh build nss # NSS module + ldconfig |
| 60 | +./dev/dev-env.sh build broker google # Broker binary + restart |
| 61 | +./dev/dev-env.sh build all # Full install-authd |
| 62 | +``` |
| 63 | + |
| 64 | +To run tests inside the VM: |
| 65 | + |
| 66 | +```bash |
| 67 | +./dev/dev-env.sh test # All tests with race detection (default) |
| 68 | +./dev/dev-env.sh test ./internal/brokers/... # Specific package |
| 69 | +./dev/dev-env.sh test --update-golden # Auto-update golden files |
| 70 | +./dev/dev-env.sh test --skip-external # Skip VHS (requires external tools) |
| 71 | +``` |
| 72 | + |
| 73 | +Tail service logs from the host: |
| 74 | + |
| 75 | +```bash |
| 76 | +./dev/dev-env.sh logs authd # authd daemon logs |
| 77 | +./dev/dev-env.sh logs google # Google broker logs |
| 78 | +./dev/dev-env.sh logs cloud-init # Cloud-init provisioning log |
| 79 | +``` |
| 80 | + |
| 81 | +## Broker Setup |
| 82 | + |
| 83 | +```bash |
| 84 | +# Google (--issuer defaults to accounts.google.com) |
| 85 | +./dev/dev-env.sh broker google \ |
| 86 | + --client-id 843411...googleusercontent.com \ |
| 87 | + --client-secret GOCSPX-... \ |
| 88 | + --ssh-suffixes '@gmail.com' |
| 89 | + |
| 90 | +# Microsoft Entra ID |
| 91 | +./dev/dev-env.sh broker msentraid \ |
| 92 | + --issuer https://login.microsoftonline.com/TENANT_ID/v2.0 \ |
| 93 | + --client-id CLIENT_ID \ |
| 94 | + --ssh-suffixes '@yourdomain.com' |
| 95 | + |
| 96 | +# Generic OIDC (Keycloak, etc.) |
| 97 | +./dev/dev-env.sh broker oidc \ |
| 98 | + --issuer https://keycloak.example.com/realms/myrealm \ |
| 99 | + --client-id authd-client --client-secret SECRET \ |
| 100 | + --ssh-suffixes '*' |
| 101 | +``` |
| 102 | + |
| 103 | +The `broker` command patches credentials, enables, and restarts the service automatically. |
| 104 | +Add `--rebuild` to recompile from source (e.g. after pulling broker changes). |
| 105 | +Use `broker <variant> edit` to open `broker.conf` directly in your editor. |
| 106 | + |
| 107 | +## Validation |
| 108 | + |
| 109 | +After installing authd (and optionally a broker), verify the full stack: |
| 110 | + |
| 111 | +```bash |
| 112 | +./dev/dev-env.sh validate |
| 113 | +``` |
| 114 | + |
| 115 | +Checks: toolchain, authd.socket, PAM module, NSS config, broker registration. |
| 116 | + |
| 117 | +## Troubleshooting |
| 118 | + |
| 119 | +| Problem | Check | |
| 120 | +|---------|-------| |
| 121 | +| VM won't start | `lxc info authd-dev` | |
| 122 | +| Provisioning failed | `./dev/dev-env.sh logs cloud-init` or `lxc exec authd-dev -- cloud-init status` | |
| 123 | +| Build failed during `up` | `./dev/dev-env.sh exec ./dev/scripts/install-authd` to retry | |
| 124 | +| Wrong Go version | `which go` should be `/usr/local/go/bin/go`, not `/usr/bin/go` | |
| 125 | +| authd won't start | `sudo systemctl status authd.socket` (authd uses socket activation) | |
| 126 | +| SSH login rejects user | `ssh_allowed_suffixes_first_auth` must be set in broker.conf | |
| 127 | +| GDM console login password | `cat ~/.config/<vm-name>/vm-password` (default: `~/.config/authd-dev/vm-password`) | |
| 128 | +| VGA console freezes immediately | See [Known issue: VGA console on HiDPI](#known-issues) below | |
| 129 | + |
| 130 | +**Recovery from failed provisioning:** `./dev/dev-env.sh down --force && ./dev/dev-env.sh up` |
| 131 | + |
| 132 | +**Re-running install scripts:** `./dev/dev-env.sh exec ./dev/scripts/install-authd` is safe to re-run (idempotent config, rebuilds binaries). |
| 133 | +`broker` auto-detects whether a binary exists: if it does, only credentials are patched (no rebuild). Pass `--rebuild` to recompile from source. |
| 134 | + |
| 135 | +**Snapshots:** `up` creates two snapshots: `clean` (toolchain only, pre-build) and `installed` (authd + PAM + NSS built; no broker credentials — run `./dev/dev-env.sh broker <variant>` to configure). |
| 136 | +Use `./dev/dev-env.sh restore installed` to reset to a freshly built state. |
| 137 | + |
| 138 | +**Go/Rust versions** are auto-synced from `go.mod` and `authd-oidc-brokers/rust-toolchain.toml` |
| 139 | +at VM creation time. No manual version management needed. |
| 140 | + |
| 141 | +## GDM / VGA Console |
| 142 | + |
| 143 | +The VM runs GDM at `graphical.target` so you can test real GDM login flows. |
| 144 | + |
| 145 | +**Accessing the GDM screen:** |
| 146 | +```bash |
| 147 | +lxc console authd-dev --type=vga # Opens SPICE viewer (requires virt-viewer on host) |
| 148 | +``` |
| 149 | + |
| 150 | +The default login password is random-generated at VM creation time: |
| 151 | +```bash |
| 152 | +cat ~/.config/authd-dev/vm-password # default VM name |
| 153 | +cat ~/.config/<vm-name>/vm-password # custom --name |
| 154 | +``` |
| 155 | + |
| 156 | +**Known issues:** |
| 157 | + |
| 158 | +| Issue | Status | Workaround | |
| 159 | +|-------|--------|------------| |
| 160 | +| **VGA console freezes on HiDPI displays (>1440p)** | [lxd#17606](https://github.com/canonical/lxd/issues/17606) — open bug, Ubuntu 25.10, LXD 6.6 | Lower host resolution to ≤1440p before opening console; or use LXD web UI (`lxc config show authd-dev` → connect on `:8443`) | |
| 161 | +| **VGA console drops on VM reboot** | [lxd#16184](https://github.com/canonical/lxd/issues/16184) — open, targeted for LXD 26.04 | Re-run `lxc console authd-dev --type=vga` after reboot | |
| 162 | + |
| 163 | +> **Wayland note:** `remote-viewer` (from `virt-viewer`) runs via XWayland on Wayland hosts. |
| 164 | +> The freeze issue is worse on Wayland + HiDPI due to SPICE resolution negotiation. |
| 165 | +> Using X11 (`DISPLAY=:0` session) or lowering resolution are the practical |
| 166 | +> workarounds until lxd#17606 is resolved. |
| 167 | +
|
| 168 | +## File Layout |
| 169 | + |
| 170 | +``` |
| 171 | +dev/ |
| 172 | +├── dev-env.sh # VM lifecycle + build (run from host) |
| 173 | +├── cloud-init.yaml # VM provisioning template (Go, Rust, deps, GDM) |
| 174 | +├── DEV-GUIDE.md # This file |
| 175 | +├── lib/ |
| 176 | +│ └── common.sh # Shared helpers (output, build, variant config) |
| 177 | +└── scripts/ |
| 178 | + ├── install-authd # Build + install authd + PAM + NSS + configure (verbose mode) |
| 179 | + └── install-broker # Configure or build+install OIDC broker + D-Bus + systemd |
| 180 | +``` |
0 commit comments