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]
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"]