Releases: TesseraLabs/tessera
Release list
v0.5.0
Tessera 0.5.0
Two things define this release: certificate login now works on Windows, and the role model was simplified down to one idea — the account you log into is the role.
That second change touches nearly every surface (login, issuance, config), so read the breaking section before upgrading. Certificates issued through the normal path keep working; the login name and a few issuance arguments change.
Highlights
- Windows certificate login. A credential provider on the logon screen plus an engine service under
LocalSystem. The verification core is reused unchanged — only platform guards were added. The engineer presents removable media, picks a role, enters the PIN, and lands on the desktop. The role does not grant rights yet: it is selected, checked against what the certificate allows, and journalled — granting is still ahead. - One open host instead of feature-flag builds. Platform enforcement backends ship as signed plugins and are selected at runtime via
[mac] backend. The signature is verified before the.sois loaded; any rejection degrades to the stub backend. - The role is the login account.
ssh serv@device— the requested role equalsPAM_USER, and there is no other source of it. - Revocation mode must be stated.
[trust.revocation].modeis now mandatory: a missing section no longer silently picks a policy for you.
Breaking changes
Role selection. The <user>+<role> suffix and the PAM role prompt are gone. Log into a role account named after the role. Rewriting PAM_USER is gone with them — while the module substituted the name read by the stack, the difference between "before" and "after" was observable to other modules in the stack, the same class of problem that produced CVE-2021-3560 in polkit. An account name that does not match ^[a-z][a-z0-9-]{0,15}$ is rejected before the token is touched.
Migration: replace ivanov+serv@device with serv@device, using a certificate whose pam_cert_allowed_roles contains serv. Role accounts must exist on the device beforehand, as ordinary accounts — a uid outside the ordinary-user range is refused.
One admission list. pam_cert_allowed_roles is it. The pam_cert_user_binding extension, issuer issue-leaf --user, and the [[user_mapping]] config section are removed. Once the login account name is the role, user_binding and allowed_roles were checked against the same string; [[user_mapping]] went for a different reason — it let the constrained side declare its own admission.
Migration: drop the section from config.toml; replace --user <account> with --role <role> — the same name. Previously issued certificates keep working: pam_cert_user_binding is ignored like any unknown non-critical extension. OID 2.25.215438916728501023845629178354627 is retired and will not be reused.
Issuance envelopes must be explicit. issuer issue-root and issuer issue-ca now require --allow-role and reject --max-ttl 0. The old defaults produced a CA that looked valid, entered the issuance journal, and never authenticated anyone. --max-ttl now defaults by what the envelope bounds: 31536000 for issue-root, 14400 for issue-ca.
[roles].enforce removed — the role is always checked. The old default ("false") was incompatible with our own issuance: certificates from the standard issuer always carry delegation envelopes, and a login without a selected role rejects any such chain.
issuer serve removed. The open issuer is a command-line issuance tool. The web cabinet and the issuance agent ship separately, through the commercial tooling; the cabinet left this repository along with its specification. The operator-confirmation module stays as a library API behind the native feature. Command-line issuance is unchanged.
Smaller ones. GOST via OpenSSL requires an explicit gost_engine_path. Daemon persistent state moved to /var/lib/tessera/daemon/. pkcs11_locking_mode now defaults to mutex rather than os.
Security
- Session and account phases act only under the identity that passed admission.
PAM_USERbelongs to the application, and nothing pins it betweenpam_sm_authenticateandpam_sm_open_session. The session phase used to re-read it and pass it straight into the session MAC label and privileged hooks — substituting the certificate CN on a read failure, i.e. the engineer's identity in place of the role account name. The name is now checked against the role fixed at authentication time, and a mismatch fails closed:PAM_SESSION_ERRinopen_session,PAM_PERM_DENIEDinacct_mgmt, hooks skipped inclose_session. There is no fallback name under any outcome. - Config, trust anchors and intermediates, CRLs, the PKCS#11 module, the GOST engine, standalone roles and device tags are all validated along a fully root-controlled path. A symlink, a non-root owner, or group/world write fails closed.
- A malformed but present
MAX_INTEGRITYextension is no longer treated as absent. - The unmaintained
ab_glyph -> owned_ttf_parser -> ttf-parserchain is gone; the wallpaper writer moved toskrifa.
Fixed
- The PKCS#11 library is initialized once per process, not once per backend load.
C_Initializeis process-global provider state; calling it concurrently killed the authentication process outright on Rutoken'srtpkcs11ecp2.14.1. The context now lives in a process-global registry keyed by the canonicalized module path.C_Finalizeis never called: it would deinitialize the provider for an unrelated PKCS#11 consumer in the same process (pam_pkcs11,sshdwithPKCS11Provider) that has no way to find out. The defect went unnoticed for three years because the whole PKCS#11 path was exercised against SoftHSM2, which survives the race. - An issued shift leaf can authenticate again.
issuer issue-leafemitted neitherkeyUsagenorextendedKeyUsage, both of which leaf validation requires — so every certificate issued through the standard path was rejected at the first gate. Issuance now self-checks the signed artifact through the same validation function the module uses. - PIN exhaustion returns
PAM_MAXTRIES(11), not 8. The code8isPAM_CRED_INSUFFICIENT; applications were told "cannot obtain credentials" instead of "attempts exhausted". issuernow defaults toprofile_version = 0, matching what the module expects.
Packages
| Asset | Target |
|---|---|
tessera_0.5.0-1_amd64-astra.deb |
Astra Linux SE 1.8 — production build |
tessera_0.5.0-1_amd64-ubuntu.deb |
Ubuntu 22.04 — evaluation build |
issuer-linux-x86_64, issuer-macos-arm64, issuer-windows-x86_64.exe |
Command-line issuance tool |
Install and integration guide: docs/ru/install.md (English). Reference documentation in docs/ is Russian-primary; README.md is the English entry point.
Licensing
Dual-licensed: AGPL-3.0 OR commercial.
Tessera 0.4.0 — first public release
Tessera 0.4.0 — first public release
Tessera is a Linux PAM module for X.509 certificate authentication, built for fleets of isolated and unattended machines: terminals, kiosks, dedicated workstations and other zero-egress environments where no directory or auth server is reachable at login time.
An engineer carries their credential — a PKCS#12 container on a USB stick or a PKCS#11 hardware token (Rutoken, JaCarta) — and the device verifies it locally: certificate chain, host binding, revocation, then opens a session with the rights of the role encoded in the certificate.
Highlights
- Fully offline authentication — chain verification, host binding and revocation checks happen on the device; no network required at login.
- RSA / ECDSA and GOST certificate chains (gost-engine loaded only when a GOST chain is present).
- Host binding — a certificate is valid only on the machines it was issued for; a stolen stick is useless on a neighbouring device.
- Revocation: offline CRL with TTL discipline, plus OCSP for connected hosts.
- Session guard (
monitord) — configurable reaction to credential removal: lock, logout, custom hook, or shutdown; grace window for accidental re-insertion. - Roles — named permission sets activated per session. On Astra Linux the session integrity level (МКЦ) is enforced today; the role format also carries groups / sudo / resource limits, with OS enforcement under active development (see
openspec/changes/linux-session-enforcement). - Astra Linux polish — fly-dm greeter integration: the device shows its
host_idright on the login screen wallpaper, so an engineer can verify what machine they are unlocking. - Operations tooling —
tessera checkconfig validator,dump-host-idhardware probe report, clone-image bootstrap flow for imaging-based rollouts.
Packages
| Asset | Target |
|---|---|
tessera_0.4.0-1_amd64-astra.deb |
Astra Linux SE 1.8 — production build |
tessera_0.4.0-1_amd64-ubuntu.deb |
Ubuntu 22.04 — evaluation build |
Install and integration guide: docs/install.md. Reference documentation in docs/ is Russian-primary; README.md is the English entry point.
Licensing
Dual-licensed: AGPL-3.0 OR commercial. Earlier releases (up to v0.3.19, as pam-certauth) were published under Apache-2.0 and remain available under it.
Contributions are welcome — see CONTRIBUTING.md (a CLA applies).