Skip to content

tessera contributor guide

This document is a guide for a developer who is opening the repository for the first time and wants to make a change. The goal: a working environment, passing tests, and a first PR in a single day.

Astra Linux SE / Ubuntu 22.04 / Debian 12:

Terminal window
sudo apt install -y \
build-essential pkg-config \
libssl-dev libudev-dev libdbus-1-dev libpam0g-dev libsystemd-dev \
softhsm2 opensc opensc-pkcs11 \
pamtester clang

The Rust toolchain is pinned in rust-toolchain.toml. If rustup is present, the toolchain is downloaded automatically:

Terminal window
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup show # picks the version from rust-toolchain.toml
Terminal window
cargo build --workspace
cargo build --workspace --release
  • Default: no special features.
  • tessera_core/pkcs11-tests — enables the integration tests that require a real gost-engine or softhsm2. The recipe for running them with softhsm2 token initialization is in §2.2.
Terminal window
cargo test --workspace

All unit and integration tests must pass.

Terminal window
sudo apt install softhsm2 opensc-pkcs11
softhsm2-util --init-token --slot 0 \
--label test --pin 1234 --so-pin 5678
SOFTHSM2_CONF=/etc/softhsm/softhsm2.conf \
cargo test --workspace --features tessera_core/pkcs11-tests

The PKCS#11 tests add an extra set of integration checks (module loading, certificate lookup, the CKA_EXTRACTABLE check).

Requires Linux + root + an installed tessera:

Terminal window
# In a separate Astra SE 1.8 VM:
sudo apt install ./target/release/tessera_0.4.0-1_amd64.deb
sudo /usr/share/tessera/integrate-pam.sh --mode=2fa /etc/pam.d/sudo
pamtester sudo alice authenticate

A .pre-commit-config.yaml is shipped at the root of the repository. To install:

Terminal window
pip install pre-commit
pre-commit install

What is checked on commit:

  • cargo fmt --all -- --check;
  • cargo clippy --workspace --all-targets -- -D warnings;
  • cargo deny check;
  • cargo test --workspace;
  • the syntax of bash scripts (bash -n);
  • the Cargo.toml version matching debian/changelog;
  • the absence of MAX_INTEGRITY OID placeholders in tracked files.

If you do not have the pre-commit framework, you can run the commands manually:

Terminal window
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace

The format is Conventional Commits:

<type>(<scope>): <subject>
<body>
<footer>

Commit messages are in English. Examples:

  • feat(monitord): handle suspend/resume via D-Bus
  • fix(core): correct CRL freshness check for mode = "crl"
  • docs(install): add Mode A scenario with FAT32 media
  • chore: bump serde to 1.0.x
  • refactor(proto): rename Pong to HelloAck for consistency
  • test(monitord): add suspend_grace e2e test

<scope> corresponds to the crate or module: monitord, core, proto, pam, install, arch, security, release, dev.

  1. Branch off main:

    Terminal window
    git checkout -b feat/awesome-feature main
  2. Atomic commits: one logically coherent commit at a time. A PR usually contains 1–5 commits.

  3. Automatic CI runs: GitHub Actions:

  4. Code review checklist:

    • is there a test for the new functionality?
    • are the relevant docs updated (configuration, architecture, threat-model)?
    • has a new TOML field appeared without documentation?
    • does the change violate the fail-closed invariants (see architecture.md §13)?
    • is the reproducible build still intact?
  5. Merge via squash + rebase merge. Large PRs — reviewed in batches of 3–5 commits; squashed into main for a clean history.

The repo ships hooks in scripts/git-hooks/ that block commits and pushes to main on weekdays between 08:00 and 19:00 local time. Enable them once per clone:

Terminal window
git config core.hooksPath scripts/git-hooks

git commit --no-verify / git push --no-verify override in emergencies.

The current support is implemented in crates/tessera_core/src/token/.

Steps:

  1. Study the interfaces (PkcsModule, Session, Slot).
  2. Implement a new adapter in a submodule (for example, token/newvendor/).
  3. Register it via crypto_backend = "pkcs11_native" with pkcs11_module = "/usr/lib/libnewvendor.so".
  4. Add tests:
    • positive: module loading + certificate lookup;
    • negative: the module did not load (a nonexistent path);
    • non-extractable: the CKA_EXTRACTABLE = false check.
  5. Update the documentation:

See crates/tessera_core/src/host_identity/.

Steps:

  1. Create a <source>.rs module implementing the HostIdSource trait.
  2. Register it in chain.rs (HostIdentityResolver::from_validated).
  3. Add it to RawHostIdentity::sources (name validation).
  4. Add it to HostIdSourceKind (the associated enum).
  5. Tests:
    • positive: the source returns a value;
    • negative: the source is unavailable → the next in the chain fires.
  6. Update docs/configuration.md (the [host_identity] table) and architecture.md §12.

8.1 Where the certificate authorization logic lives

Section titled “8.1 Where the certificate authorization logic lives”

The authorization of “which user on which host” is fully described in the certificate itself through X.509 extensions and is verified in code:

  • crates/tessera_core/src/x509/host_binding_ext.rs — parsing of the pam_cert_host_binding extension (the OID and ASN.1 structure are in x509/oids.rs).
  • crates/tessera_core/src/x509/allowed_roles_ext.rs — parsing of the pam_cert_allowed_roles extension.
  • verify_cert_scope — the final matching of the parsed entries against host_id_hash and the requested role, which is also pam_user. See also docs/cert-issuance.md for the semantics of the entries.

SemVer 2.0.0 semantics:

  • MAJOR — breaking changes (incompatible changes to the config.toml schema, the IPC protocol, removed configuration options).
  • MINOR — backward-compatible new functionality (a new PKCS#11 provider, a new host_id source, a new stage in hooks).
  • PATCH — bug fixes, doc updates, dependency updates without an API change.

Each MAJOR release requires: