Skip to content

Releases: TesseraLabs/tessera

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 02 Aug 10:06
v0.5.0
83afd14

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 .so is loaded; any rejection degrades to the stub backend.
  • The role is the login account. ssh serv@device — the requested role equals PAM_USER, and there is no other source of it.
  • Revocation mode must be stated. [trust.revocation].mode is 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_USER belongs to the application, and nothing pins it between pam_sm_authenticate and pam_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_ERR in open_session, PAM_PERM_DENIED in acct_mgmt, hooks skipped in close_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_INTEGRITY extension is no longer treated as absent.
  • The unmaintained ab_glyph -> owned_ttf_parser -> ttf-parser chain is gone; the wallpaper writer moved to skrifa.

Fixed

  • The PKCS#11 library is initialized once per process, not once per backend load. C_Initialize is process-global provider state; calling it concurrently killed the authentication process outright on Rutoken's rtpkcs11ecp 2.14.1. The context now lives in a process-global registry keyed by the canonicalized module path. C_Finalize is never called: it would deinitialize the provider for an unrelated PKCS#11 consumer in the same process (pam_pkcs11, sshd with PKCS11Provider) 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-leaf emitted neither keyUsage nor extendedKeyUsage, 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 code 8 is PAM_CRED_INSUFFICIENT; applications were told "cannot obtain credentials" instead of "attempts exhausted".
  • issuer now defaults to profile_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

Choose a tag to compare

@github-actions github-actions released this 07 Jul 08:44
v0.4.0
2006c39

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_id right on the login screen wallpaper, so an engineer can verify what machine they are unlocking.
  • Operations toolingtessera check config validator, dump-host-id hardware 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).