authd is an authentication daemon for cloud-based identity providers (MS Entra ID, Google IAM). It's a hybrid Go/Rust/C project that provides:
- authd daemon (Go): Main authentication service with gRPC API
- PAM modules (Go): Two implementations - native shared library for GDM, and C-wrapper+executable for other PAM apps
- NSS module (Rust): Name Service Switch integration for user/group lookups
- Brokers (Go): Pluggable D-Bus-based providers that interface with identity providers
- Internal: gRPC for PAM/NSS ↔ authd (defined in
internal/proto/authd/authd.proto) - External: D-Bus for authd ↔ brokers (interface in
examplebroker/com.ubuntu.auth.ExampleBroker.xml) - Daemon: Systemd socket activation via
internal/daemon/daemon.go - Data flow: PAM/NSS → gRPC → authd → D-Bus → broker → identity provider
cmd/authd/,cmd/authctl/: Main binariesinternal/brokers/: Broker manager and D-Bus integrationinternal/services/: gRPC service implementations (PAM, NSS, user management)internal/users/: User/group database management (SQLite + BoltDB legacy)pam/: PAM module with two build modes (seepam/Hacking.md)nss/: Rust NSS module usinglibnsscrateexamplebroker/: Reference broker implementation
# Full Debian package (includes all components + tests)
debuild --prepend-path=${HOME}/.cargo/bin
# Individual components (development)
go build ./cmd/authd # authd daemon only
go generate ./pam/ && go build -tags pam_binary_exec -o ./pam/authd-pam ./pam # PAM test client
cargo build # NSS (debug mode)- Run tests:
go test ./...(add-racefor race detection) - Golden files: Use
internal/testutils/goldenpackage- Update with
TESTS_UPDATE_GOLDEN=1 go test ./... - Compare/update:
golden.CheckOrUpdate(t, got)orgolden.CheckOrUpdateYAML(t, got)
- Update with
- Test helpers with underscores: Functions prefixed
Z_ForTests_are test-only exports (e.g.,Z_ForTests_CreateDBFromYAML) - Environment variables:
AUTHD_SKIP_EXTERNAL_DEPENDENT_TESTS=1: Skip tests requiring external tools (vhs)AUTHD_SKIP_ROOT_TESTS=1: Skip tests that fail when run as root
Critical: Run go generate before building PAM or when modifying protobuf files:
go generate ./pam/ # PAM module (creates .so files)
go generate ./internal/proto/authd/ # Regenerate protobuf
go generate ./shell-completion/ # Shell completions- Brokers are discovered from
/usr/share/authd/brokers/*.conf(D-Bus service files) - First broker is always the local broker (no config file)
- Manager in
internal/brokers/manager.gohandles session→broker and user→broker mappings - Brokers must implement the D-Bus interface defined in
internal/brokers/dbusbroker.go
The PAM module has two implementations (see pam/Hacking.md):
- GDM mode (
pam_authd.so): Native Go shared library with GDM JSON protocol support - Generic mode (
pam_authd_exec.so+authd-pamexecutable): C wrapper launching Go program via private D-Bus- Required for reliability with non-GDM PAM apps (avoids Go threading issues)
- Migrating from BoltDB to SQLite:
internal/users/db/handles both - User/group data cached locally in
/var/lib/authd/authd.db - ID allocation:
internal/users/idlimitsgenerator/generates UID/GID ranges - Group file updates:
internal/users/localentries/handles local system files
- Use
testify/requirefor assertions (notassert) - Golden files in
testdata/golden/subdirectories matching test structure - Test-only exports via
export_test.gofiles (no build tag, package-level visibility) - PAM integration tests use
vhstapes inpam/integration-tests/testdata/tapes/
- Update
internal/proto/authd/authd.proto - Run
go generate ./internal/proto/authd/ - Implement in service (e.g.,
internal/services/pam/pam.go) - Add tests with golden files
- Implement D-Bus interface from
examplebroker/com.ubuntu.auth.ExampleBroker.xml - Create
.conffile in/usr/share/authd/brokers/ - Register D-Bus service with systemd
- Logs via
github.com/canonical/authd/logpackage (supports systemd journal) - Enable debug:
authd daemon -vvv(3 levels of verbosity) - Socket path:
/run/authd.sock(override withAUTHD_NSS_SOCKETfor NSS tests)
- Go: See
go.modfor version requirements, uses go modules with vendoring - Rust: Cargo with vendor filtering (see
Cargo.tomlworkspace) - Required:
libpam-dev,libglib2.0-dev,protoc,cargo-vendor-filterer - Optional:
vhs(PAM CLI tests),delta(colored diffs in tests)
- Follow Effective Go for Go style conventions
- Use
go fmtandgofmt -s - Rust: Standard cargo fmt conventions