id = "google-authenticator-libpam" name = "Google Authenticator PAM module" homepage = "https://github.com/google/google-authenticator-libpam" description = "Example PAM module demonstrating two-factor authentication for logging into servers via SSH, OpenVPN, etc." executables = ["google-authenticator"] platforms = ["macos", "linux"] [dotfiles] # The upstream README's "Setting up a user" section says the # google-authenticator binary creates this secret key in the user's home. paths = [] secret = ["~/.google_authenticator"] [commands] format = 1 label = "Set up one-time passcodes" description = "Create ~/.google_authenticator for the current user with non-interactive options. Rate limit and window tuning beyond the basics are left out." quality = "ai-draft" parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = true, short_bundles = true } [[commands.source]] id = "man" kind = "manual" url = "https://raw.githubusercontent.com/google/google-authenticator-libpam/master/man/google-authenticator.1" revision = "master 2026-10-27" evidence = """ -c, --counter-based -t, --time-based -w, --window-size=W -W, --minimal-window -D, --allow-reuse, -d, --disallow-reuse -s, --secret=FILE -f, --force -l, --label=LABEL -i, --issuer=ISSUER -Q, --qr-mode=none|ansi|utf8 -e, --emergency-codes=N -q, --quiet """ [[commands.field]] id = "mode" label = "Token type" type = "boolean" option = ["--time-based", "-t"] sources = ["man"] [[commands.field]] id = "disallow_reuse" label = "Disallow token reuse" type = "boolean" option = ["--disallow-reuse", "-d"] sources = ["man"] [[commands.field]] id = "force" label = "Write without asking" type = "boolean" option = ["--force", "-f"] effect = "overwrite" sources = ["man"] [[commands.field]] id = "label" label = "Label" type = "string" option = ["--label", "-l"] sources = ["man"] [[commands.field]] id = "issuer" label = "Issuer" type = "string" option = ["--issuer", "-i"] sources = ["man"] [[commands.field]] id = "window_size" label = "Window size" description = "Between 1 and 21." type = "integer" option = ["--window-size", "-w"] sources = ["man"] [[commands.field]] id = "secret" label = "Secret file" type = "path" option = ["--secret", "-s"] path = { kind = "file", role = "output", must_exist = false } effect = "overwrite" sources = ["man"] [[commands.field]] id = "qr_mode" label = "QR code mode" type = "enum" option = ["--qr-mode", "-Q"] choices = [{ value = "none", label = "None" }, { value = "ansi", label = "ANSI" }, { value = "utf8", label = "UTF-8" }] sources = ["man"] [[commands.field]] id = "emergency_codes" label = "Emergency codes" type = "integer" option = ["--emergency-codes", "-e"] sources = ["man"] [[commands.task]] id = "totp" label = "Time-based setup" set = { mode = [true], disallow_reuse = [true] } fields = ["mode", "disallow_reuse", "force", "label", "issuer", "window_size", "qr_mode", "emergency_codes", "secret"] required = [] [[commands.group]] id = "basic" label = "Basic" fields = ["mode", "disallow_reuse", "force", "label", "issuer", "qr_mode"] [[commands.group]] id = "advanced" label = "Advanced" fields = ["window_size", "emergency_codes", "secret"]