Skip to main content

authkeys

PyPI version Python versions Documentation License: MIT

A pluggable OpenSSH AuthorizedKeysCommand provider. It resolves a user's authorized SSH keys from one or more configured sources — local key files, an HTTP endpoint, a GitHub-style .keys endpoint, or LDAP-stored X.509 certificates — with optional TTL caching, user/group aliasing, and a small unattended HTTP key server for hosts that fetch keys centrally.

Built on the duho declarative CLI framework.

Install

pip install authkeys            # core (file source only)
pip install authkeys[http]      # + HTTP source (requests)
pip install authkeys[ldap]      # + LDAP cert source (ldap3, cryptography)
pip install authkeys[all]       # everything

authkeys targets POSIX systems (it reads the system user/group databases via pwd/grp). The package imports on any platform for testing, but resolution requires a POSIX host.

Usage

authkeys resolve alice          # print alice's authorized keys
authkeys alice                  # 'resolve' is the default command
authkeys -c /etc/authkeys.cfg serve --listen 127.0.0.1:8090

Wire it into sshd_config:

AuthorizedKeysCommand /usr/bin/authkeys resolve %u
AuthorizedKeysCommandUser authkeys

Run the command as a dedicated account that does nothing else (here authkeys), as sshd_config(5) recommends: with the on-disk cache, whatever runs as that account can write cache entries, and so keys.

Alongside those, authkeys check resolves a user with per-source tracing on stderr (which source produced which key), authkeys cache show|purge|warm inspects and manages the on-disk cache, and authkeys completion bash|zsh|fish|powershell prints a shell completion script. resolve and check also take --format authorized_keys|json, where json emits one object per key with type, key, comment, and options for scripting. See the CLI guide for details.

resolve and check exit 0 on success — including when no keys were found, which sshd reads as "no keys" — 2 on a usage error and 3 on a configuration or internal error, never a traceback.

Configuration

authkeys reads one TOML file: /etc/authkeys.cfg, or the file named with --config (-c, before the command) or AUTHKEYS_CONFIG. ${env.NAME} is replaced from the environment, and a key authkeys does not know is logged as a warning instead of being silently ignored. See examples/authkeys.cfg for a fully commented example.

[cache]
backend = "memory"
expire = 3600
expired_on_error = true

[source.files]
backend = "file"
paths = ["authorized_keys", "authorized_keys2"]

[source.ldap]
backend = "ldap"
server = "ldaps://ldap.example.com:636"
basedn = "o=Example,c=US"

Sources

backend Reads keys from Extra
file ~/.ssh/authorized_keys* files —
http an HTTP URL ({username} templated) authkeys[http]
github a GitHub (or similar) .keys endpoint authkeys[http]
ldap X.509 certs in an LDAP directory (Kerberos with the machine account by default; python-ldap or ldap3) authkeys[ldap], or a system python-ldap

Each [source.<name>] table supports enabled and cached (both default true) and an optional sanitize callable to rewrite or drop keys. Other distributions can add sources through the authkeys.sources entry-point group.

Caching

  • memory — per-process, in-memory (default).
  • file — on disk under path, shared across invocations.

With expired_on_error = true, a source failure falls back to the last-known (expired) cached keys instead of returning nothing — useful when the SSH login must not be blocked by a transient LDAP/HTTP outage.

User / group aliasing

A user's ~/.ssh/authkeys.cfg may grant other principals' keys to that user's account:

[authorized]
users = ["alice", "bob"]
groups = ["admins"]

HTTP key server (authkeys serve)

For hosts that can't run the command locally, authkeys serve exposes the same resolution over HTTP:

GET /keys?username=alice&apikey=<key>

Where it listens (--listen, netimps syntax, IPv6 included), TLS (certificate/key), the path and the limits come from the [serve] table, from AUTHKEYS_SERVE_<OPTION> or from the command line; the API key only from [serve] api_key. It is compared in constant time and may also be sent as Authorization: Bearer <key>; pull it from the environment with api_key = "${env.AUTHKEYS_APIKEY}" to keep it off disk. If no API key is configured, authentication is disabled — only listen on a trusted interface in that case.

License

MIT — see LICENSE.

Metadata

Release files for authkeys 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for authkeys 0.5.0
File Size Uploaded Provenance
authkeys-0.5.0.tar.gz 100.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for authkeys 0.5.0
File Interpreter ABI Platform
authkeys-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 158.0 kB

Release files / authkeys-0.5.0.tar.gz

Download URL authkeys-0.5.0.tar.gz
Size 100.6 kB
Tags Source
SHA-256 checksum
How to use checksums
eefb0a206a1ca825655ef97fada5132d37c79774c52040e851c84140d6e385b9
BLAKE2b-256 checksum
How to use checksums
95d9a2bd042677be98631a4f6d48cccf236be5b91395fa9a604db10a1893e2c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / authkeys-0.5.0-py3-none-any.whl

Download URL authkeys-0.5.0-py3-none-any.whl
Size 57.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0b3571e88ba6b3b0a36b535acfa67959c0bd581c4abfa64764543d0cf224f4f2
BLAKE2b-256 checksum
How to use checksums
8f632b565f3def77c2596d3108b86ae59039b7d9dc8c6155d92811c94a5bc453
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for authkeys 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for authkeys-0.5.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page