passbox 2.1.0

A password store for agents, where a fingerprint releases one secret into one process
[package]
name = "passbox"
version = "2.1.0"
edition = "2024"
description = "A password store for agents, where a fingerprint releases one secret into one process"
license = "MIT"
repository = "https://github.com/gabrielkoerich/passbox"
homepage = "https://passbox.gabrielkoerich.com"
readme = "README.md"
keywords = ["secrets", "password", "agents", "touch-id"]
categories = ["authentication", "command-line-utilities"]
include = ["/src/**", "/plugins/**", "/swift/**", "/build.rs", "/README.md", "/SKILL.md", "/LICENSE"]

[features]
# The host holds the Enclave, the store and the broker. A client only asks one.
default = ["host"]
host = []
# Tests only. Swaps the Secure Enclave helper for src/bin/fake-enclave.rs, and a release build
# with it does not compile. Never enable it for anything that ships.
mock-enclave = ["host"]

[[bin]]
name = "fake-enclave"
path = "src/bin/fake-enclave.rs"
required-features = ["mock-enclave"]

[lints.rust]
unsafe_op_in_unsafe_fn = "warn"          # each unsafe op needs its own unsafe block
missing_debug_implementations = "warn"   # every public type implements Debug
missing_docs = "warn"                    # [lib] document every public item
unreachable_pub = "warn"                 # pub items that aren't actually exported
rust_2018_idioms = { level = "warn", priority = -1 } # 2018-edition idioms, e.g. Formatter<'_>

[lints.clippy]
# Groups first, at lower priority so the individual settings below win.
all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }

# Panics: return errors, and give every intentional panic a reason.
unwrap_used = "warn"                     # use ?, or expect("why this cannot fail")
expect_used = "allow"                    # expect with a reason is the sanctioned form
panic_in_result_fn = "warn"              # a fn returning Result shouldn't also panic
missing_panics_doc = "warn"              # [lib] document reachable panics under # Panics
missing_errors_doc = "warn"              # [lib] document failures under # Errors
missing_assert_message = "warn"          # assert! says what went wrong (quiet inside #[test])

# Suppressions must explain themselves and expire when no longer needed.
allow_attributes = "warn"                # prefer #[expect] over #[allow] (needs rust-version 1.81+)
allow_attributes_without_reason = "warn" # every suppression says why (needs rust-version 1.81+)

# Unsafe must be justified.
undocumented_unsafe_blocks = "warn"      # // SAFETY: comment on every unsafe block
multiple_unsafe_ops_per_block = "warn"   # one unsafe operation per block

# API shape.
fn_params_excessive_bools = "warn"       # bool parameters: use an enum or two methods
struct_excessive_bools = "warn"          # many bool fields: use an enum or bitflags
clone_on_ref_ptr = "warn"                # write Rc::clone(&x) so cheap clones are visible
redundant_clone = "warn"                 # a clone whose original is never used again
rc_buffer = "warn"                       # Rc<String> / Rc<Vec<T>>: use Rc<str> / Rc<[T]>

# Evolution.
exhaustive_enums = "warn"                # [lib] exported enums are #[non_exhaustive] (quiet in binaries)

# Idioms.
string_add = "warn"                      # build strings with format! or push_str, not +
wildcard_imports = "warn"                # no glob imports (use super::* in tests is allowed)
absolute_paths = "warn"                   # import a path with `use`, never write crate::ssh::label inline

# Output and debugging leftovers.
dbg_macro = "warn"
todo = "warn"
print_stdout = "warn"                    # [lib] libraries log, they don't print
print_stderr = "warn"                    # [lib] libraries log, they don't print

# Casts that silently lose information.
as_conversions = "warn"                  # prefer From / TryFrom
cast_possible_truncation = "warn"
cast_sign_loss = "warn"

# Pedantic lints that are mostly noise in practice, or that the skill disagrees with.
module_name_repetitions = "allow"
must_use_candidate = "allow"
module_inception = "allow"               # a leaf module named after its main item is fine
enum_glob_use = "allow"                  # use Enum::* inside a function that matches on it

[dependencies]
# `plugin` is back for the YubiKey wrap alone. It carries no prompt wording of its own,
# so it cannot take over the Touch ID text, which is why it was dropped before.
age = { version = "0.12.1", features = ["plugin", "cli-common"] }
anyhow = "1.0.104"
clap = { version = "4.6.7", features = ["derive"] }
hex = "0.4.3"
libc = "0.2.180"
rand = "0.10.3"
rpassword = "7.4.0"
secrecy = "0.10.3"
serde = { version = "1.0.229", features = ["derive"] }
serde_json = "1.0.151"
sha2 = "0.10.9"
signature = "2.2.0"
# Ed25519 and P-256 only. RSA would pull in the `rsa` crate for a key type few still make
ssh-key = { version = "0.6.7", default-features = false, features = ["std", "ed25519", "p256"] }
toml = "0.9.8"
zeroize = "1.9.0"

[dev-dependencies]
tempfile = "3.24.0"