Livy Documentation

Audit

API and code-shape audit of the current livy-tee library: duplicate surfaces, deprecated logic, dead code signals, enum clarity, and documentation status.

This audit is a design and maintenance review of the current livy-tee library, focused on four questions:

  1. Are there duplicated public methods that should be collapsed?
  2. Is there deprecated or legacy logic that should not be promoted in docs?
  3. Is there dead code or stale internal logic hiding in the crate?
  4. Are the public enums and error surfaces clear enough for production use?

Summary

The current library is in good shape structurally:

  • no meaningful dead-code signal surfaced in cargo clippy
  • public error enums are mostly clear and future-proofed with #[non_exhaustive]
  • the remaining duplicated surfaces are intentional trust-boundary wrappers
  • the main drift was in documentation, not in the core implementation

Duplication review

Intentional wrapper pairs

These are not problematic duplication; they represent distinct trust levels:

  • verify_binding() vs verify()
  • verify() vs verify_with_policy()
  • verify_fresh() vs verify_fresh_with_policy()
  • verify_quote() vs verify_quote_with_public_values()

Each pair exists to keep the common case small while preserving an explicit policy or low-level path.

No public compatibility aliases remain after this pass. The canonical names are PublicValues::read() and unauthenticated_report_data_hash_from_token().

Deprecated / legacy logic

Explicit unauthenticated helper

unauthenticated_report_data_hash_from_token() remains a valid low-level API. The explicit unauthenticated_ prefix is important because the function does not verify the JWT signature.

Unauthenticated ITA appraisal helper

appraise_evidence_unauthenticated(...) is still a valid public API, but it is not the right API for stored-attestation trust decisions. It exists for:

  • the immediate same-request ITA response
  • low-level inspection
  • specialized replay / tooling flows

For stored attestations, the intended surfaces are:

  • Attestation::verify()
  • Attestation::verify_fresh()

Dead code review

The audit did not find meaningful dead code in the shipping library path.

Validation used:

cargo clippy --all-targets -- -D warnings
cargo clippy --features mock-tee,ita-verify --all-targets -- -D warnings

The small #[allow(dead_code)] fields in ITA claims parsing are intentional: they preserve standard JWT registered claims (exp, nbf, iat) inside the deserialization model even when the crate does not read them directly after jsonwebtoken validation.

Enum clarity review

The public enums are generally clear and production-appropriate:

  • GenerateError
  • VerifyError
  • ExtractError
  • BuildIdError
  • EvidenceError
  • PublicValuesError
  • LivyEnvError
  • CloudProvider

Strengths:

  • errors are domain-specific rather than generic strings
  • VerifyError::code() and GenerateError::code() provide stable machine-readable codes
  • most evolving public enums are marked #[non_exhaustive]

Minor note:

  • CloudProvider is intentionally tiny and only models the cases the runtime selection logic currently distinguishes (Azure, Gcp)

Naming rough edges

No public enum is seriously unclear at the moment. The one mildly generic type name worth noting is Config, which is the parser configuration for livy_tee::parse. If that parser surface grows, ParseConfig would be a clearer name. Today it is small enough that this is not urgent.

Documentation status after this pass

The livy-tee docs section has been updated to match the current API:

  • verify() returns AttestationVerification, not bool
  • verify_fresh() is documented as the strict path
  • Azure verification behavior is documented as provider-specific
  • PublicValues::read() is documented as fallible
  • low-level unauthenticated helpers are documented with the correct trust boundary

Bottom line

From an API-shape and maintenance perspective, livy-tee is now in a good state for production use.

The remaining cleanup candidate is optional:

  • rename Config later if parser configuration grows beyond one field