Skip to content

The libraries, one question each

The thirteen go-authn Go modules: the question each one answers, the version these pages describe, and why they are separate modules.

Programs such as authnd and authn-bridge are built from modules that are published, versioned and tested on their own. Each answers one question, and a program imports the ones whose questions it asks.

All of them are pure Go and build with CGO_ENABLED=0.

modulethe question it answersthese pages describeimport path
mfadid enough factors answer, of enough kinds, and which ones?v0.5.0github.com/go-authn/mfa
totpis this six-digit code right, and has it been used before?v0.4.2github.com/go-authn/totp
fidohow is a security key spoken to, over 64-byte reports?v0.6.2github.com/go-authn/fido
keyfactordid the registered key answer, and did a person touch it?v0.4.2github.com/go-authn/keyfactor
directorywho is somebody, and what can prove them?v0.14.0github.com/go-authn/directory
ldapwhat are the bytes of an LDAP server?v0.8.0github.com/go-authn/ldap
krb5is this Kerberos ticket good for this service?v0.3.1github.com/go-authn/krb5
kdchow does a realm issue tickets from a directory?v0.4.3github.com/go-authn/kdc
oidcwho does this bearer token say is asking, and should it be believed?v0.4.1github.com/go-authn/oidc
samlwhat did a federation’s identity provider say about this person?v0.4.1github.com/go-authn/saml
krlis this SSH certificate or key revoked, as sshd would answer?v0.6.1github.com/go-authn/krl
servercertwhere does a daemon’s TLS server certificate come from?v0.5.2github.com/go-authn/servercert
wireguardmay this WireGuard key connect, and whose is it?v0.1.1github.com/go-authn/wireguard

How they group

Factors — whether a person is present. mfa decides how much proof is enough and knows about no device. totp is one factor: a code from a phone. fido speaks CTAP to a security key and knows about no policy; keyfactor is the one piece that imports both, and turns a key into a factor.

The directory, and its protocol. directory is the model: a person, and which credentials a source holds for them — a password, an NT hash, a verifier, SSH keys, a one-time-code secret — and, apart from them, the attributes that describe them and prove nothing. ldap is the LDAP wire protocol, as a server, and the directory schema an entry can be checked against; what it answers is the handler’s business.

Kerberos, in two halves. krb5 accepts tickets: a keytab, an AP-REQ in, an AP-REP out. kdc issues them, from a directory that holds passwords.

Federation and tokens. saml is a SAML 2.0 service provider in front of a federation such as RENATER or eduGAIN. oidc verifies the OpenID Connect tokens a provider signs — the resource-server half, with no login flow.

Revocation and certificates. krl reads, writes and checks OpenSSH key revocation lists. servercert gives a daemon its TLS certificate, from files or from ACME.

wireguard carries the signed list of WireGuard public keys people have registered with a provider, which a gateway turns into peers.

Why they are separate modules

A service that only accepts tickets never links a KDC. An NFS server verifies the tickets a client presents; it has a keytab and nothing else to do with a realm. If accepting and issuing were one module, every such server would carry a ticket-issuing code path it never runs, and the directory module a KDC reads people from, which it never uses.

This is measured, not intended. In a scratch module that imports only github.com/go-authn/krb5@v0.3.1:

$ GOWORK=off go list -deps . | grep go-authn
github.com/go-authn/krb5
$ GOWORK=off go list -m all | grep go-authn
github.com/go-authn/krb5 v0.3.1

The same command for a module that imports github.com/go-authn/kdc@v0.4.3 lists github.com/go-authn/directory and github.com/go-authn/kdc: issuing needs the people, accepting does not.

The same rule holds elsewhere. mfa imports nothing outside the standard library, and fido does not import mfa: a program that only wants to make a key blink does not carry a policy package. totp depends on mfa only, and oidc has no dependency at all. directory keeps its LDAP, SQL and HCL sources in subpackages: the core package imports nothing outside the standard library, and sqldir takes an *sql.DB, so the database driver is the program’s choice.

Every page has the same parts

The question; the go get line for the version described; a minimal example that compiles against that version; what the module refuses, from its code; and what it is checked against — the implementation that is not this one, named in its CI or its tests. Where a README and the code disagree, the page follows the code.

Created on by tannevaled

Modified on by tannevaled