keylimectl: A replacement for keylime_tenant in rust#1068
Draft
ansasaki wants to merge 41 commits intokeylime:masterfrom
Draft
keylimectl: A replacement for keylime_tenant in rust#1068ansasaki wants to merge 41 commits intokeylime:masterfrom
keylime_tenant in rust#1068ansasaki wants to merge 41 commits intokeylime:masterfrom
Conversation
b55ee8e to
da44cbc
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
7cd11bf to
9609be7
Compare
30 tasks
30 tasks
f15c57b to
d1ff80a
Compare
36 tasks
9b7d3d7 to
f1bf332
Compare
Add --timeout CLI flag, no-argument behavior with config summary and dynamic clap help, interactive configuration wizard (dialoguer), config file path tracking, formalized search paths, and integration tests. Key changes: - --timeout global flag overrides client.timeout - Running without subcommand shows config summary + clap help - `configure` subcommand with interactive wizard (wizard feature flag) and --non-interactive mode for scripted configuration - Config struct tracks loaded_from path, has_config_file() helper - .keylimectl/config.toml added as highest-priority auto-discovery path - 348 tests (340 unit + 8 integration), clippy clean across all feature combinations Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the `keylimectl info` command with subcommands for inspecting configuration, server status, agents, and TLS certificates. Info commands work even with incomplete configuration (warn on validation instead of exiting), making them useful for troubleshooting. Subcommands: - `info` (no subcommand): local diagnostics with version, features, config file search results, effective config with per-field source annotations (cli/env_var/config_file/default), KEYLIME_* env vars - `info verifier`: connect to verifier, report API version, agent count - `info registrar`: connect to registrar, report API version, agent count - `info agent <ID>`: combined verifier+registrar view with summary - `info tls`: validate cert files, check expiration, verify cert/key pair Infrastructure: - CliOverrides struct tracks which CLI args were provided for source annotation in the info command - Config::config_search_paths() exposes file search paths - RegistrarClient::api_version() public getter added - Info command gets its own match arm in main() with validation bypass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…with new CLI subcommands Convert commands/policy.rs into a directory module (commands/policy/) with the existing CRUD operations moved to crud.rs. Add new CLI subcommands for local policy tools: - policy generate runtime/measured-boot/tpm - policy sign (DSSE signing) - policy verify-signature - policy validate - policy convert (legacy format conversion) - verify evidence (top-level command for one-shot attestation) Add new error types: PolicyGenerationError, DsseError, EvidenceError. Create policy_tools module skeleton for shared policy logic. All new subcommands return "not yet implemented" stubs. Existing CRUD commands and all 372 unit tests continue to pass unchanged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ypes Add Rust types for policy schemas that match the Python implementation, enabling serialization compatibility between Python and Rust codebases. - RuntimePolicy: v1 schema with digests, excludes, keyrings, IMA config - MeasuredBootPolicy: UEFI Secure Boot reference state types - TpmPolicy: PCR mask and expected values with helper methods Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tion Add IMA measurement list parsing, flat-text and JSON allowlist parsing, exclude list parsing, and file digest calculation for local runtime policy generation via `keylimectl policy generate runtime`. - ima_parser: parse IMA logs (ima, ima-ng, ima-sig, ima-buf templates) - ima_parser: parse flat-text and JSON allowlists, exclude lists - digest: calculate file digests using OpenSSL (sha1/256/384/512/sm3) - generate: wire Runtime subcommand to parse inputs and build policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add filesystem tree scanning for rootfs digest calculation and policy merge utilities. Wire --rootfs and --skip-path CLI args to the runtime policy generate command using tokio::spawn_blocking for CPU-bound work. - filesystem: recursive directory walk with skip paths and symlink exclusion - merge: union of digests, excludes, keyrings, and ima-buf entries - runtime_policy: add deduplication to add_digest/add_keyring/add_ima_buf Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ation Add Dead Simple Signing Envelope (DSSE) support for policy signing and verification with ECDSA P-256 and X.509 certificate backends. Implements PAE (Pre-Authentication Encoding), envelope sign/verify protocol, key generation/loading, and self-signed certificate creation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…oot, and TPM policies Add structural and content validation for all three policy types with auto-detection. Validates digest formats, required fields, PCR mask consistency, and schema compatibility. Supports optional DSSE signature verification during validation via --signature-key. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add conversion from JSON and flat-text allowlists to v1 runtime policy format. Supports auto-detection of input format, exclude list merging, and verification key injection. Adds in-memory parsing helpers for JSON and flat-text allowlists to ima_parser. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add verify evidence command that posts TPM or TEE attestation evidence to the verifier's /verify/evidence endpoint. Reads quote, AK, EK files as base64, sends with nonce and policies, parses verification results including failure details. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TPM policy generation from PCR values file with index filtering and mask calculation. Add measured boot policy generation from UEFI event logs using the shared crate's UefiLogHandler, extracting S-CRTM, platform firmware, and Secure Boot variable measurements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 23 integration tests in tests/policy_tools.rs covering: - Help output for all new subcommands (generate, sign, validate, convert) - Runtime policy generation from IMA logs, allowlists, with excludes - TPM policy generation from PCR values files - Policy validation for runtime and TPM policy types - DSSE signing (ECDSA and X.509 backends) and verification - Legacy allowlist conversion (flat-text and JSON formats) - End-to-end pipeline: generate -> validate -> sign -> verify Fix bugs found during integration testing: - Remove duplicate stdout output (commands called output.success() AND main.rs dispatcher also called it, producing double JSON) - Remove default_value on --ima-measurement-list to make it truly optional (previously always read /sys/kernel/security/ima even when only --allowlist was specified) - Add PolicyAction::is_local_only() and match arm in main() so local-only policy commands (generate, sign, verify-signature, validate, convert) bypass strict TLS config validation Update ROADMAP.md to mark Phase 6 items as complete. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add policy_tools/privilege module with helpers for detecting permission errors and suggesting sudo retries. Add PrivilegeRequired error variant to PolicyGenerationError for privileged operations like TPM access, initramfs reading, and boot event log parsing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… measured boot event log Add EV_EFI_VARIABLE_AUTHORITY and EV_EFI_PLATFORM_FIRMWARE_BLOB2 event types to the shared UEFI log handler. Create uefi_event_data module for parsing UEFI_VARIABLE_DATA and EV_IPL event data structures. Extract boot chain entries (shim/grub/kernel from PCR 4), kernel command line (PCR 8), initrd/vmlinuz digests (PCR 9), MOK digests (MokList/MokListX), and vendor_db from EV_EFI_VARIABLE_AUTHORITY events. Add vmlinuz_plain_sha256 field to KernelEntry for non-SecureBoot systems. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ature flag Add tpm-local feature flag (aliases dep:tss-esapi). Implement generate_from_tpm() that opens the local TPM via TCTI, reads PCR values for requested indices and hash algorithm, and builds a TpmPolicy. On permission errors accessing /dev/tpmrm0, suggest running with sudo. Pass hash_alg through from CLI to TPM generation. Without the feature flag, --from-tpm produces a clear error naming the required feature. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ability to extract and hash files from initramfs/initrd images for runtime policy generation. Supports gzip, zstd, xz, and bzip2 compression formats with CPIO new-ASCII archive parsing. Key components: - Compression detection via magic bytes with automatic decompression - Early microcode CPIO archive detection and skipping - In-memory CPIO parsing that hashes files without extracting to disk - Privilege detection for /boot directory access with sudo suggestion Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eature flag Add --local-rpm-repo and --remote-rpm-repo options for runtime policy generation. Local repos are scanned for RPM files and their headers are parsed for file digests. Remote repos use filelists-ext.xml as a fast path, falling back to downloading individual RPMs. Key components: - RPM header parsing via pure-Rust rpm crate (no librpm-devel needed) - repomd.xml and filelists-ext.xml parsing via quick-xml - Automatic decompression of metadata files (gzip, xz, zstd, bzip2) - Feature-gated: rebuild with --features rpm-repo to enable - Replace xz2 with liblzma to avoid native library linking conflict Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… update ROADMAP Add 5 new integration tests for Phase 6b features: - Runtime help shows --ramdisk-dir, --local-rpm-repo, --remote-rpm-repo - TPM help shows --from-tpm - Nonexistent ramdisk dir fails with error - Empty ramdisk dir succeeds with no initrd digests Update ROADMAP.md to mark all deferred Phase 6 items as complete: initramfs extraction, RPM repository analysis, measured boot kernel/ bootloader/MOK extraction, and TPM PCR reading. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplify the CLI flag name for querying the registrar directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
…ion polling
The previous implementation matched operational_state against string
values, but the verifier returns it as an integer. Instead, use the
attestation_status field ("PENDING", "PASS", "FAIL") which the verifier
computes for both push and pull mode agents.
On failure, report the operational state, severity level, and last
event ID so the user understands why attestation failed. On timeout,
use the correct error type to avoid the misleading "Failed to list
verifier" message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ment The accept_tpm_signing_algs field was set to ["rsa", "ecdsa"], which are encryption algorithm names, not signing algorithm names. The verifier rejected quotes signed with rsassa because it was not in the accepted list. Use the correct signing algorithm names matching the Python tenant defaults: ["ecschnorr", "rsassa"]. Also align accept_tpm_hash_algs with tenant defaults by including sha512 and sha384, and dropping sha1. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…gent The agent expects the payload as base64-encoded AES-256-GCM ciphertext (base64(iv || ciphertext || tag), encrypted with key K). Previously, the raw file content was sent without encryption or encoding, causing "Invalid base64 encoding in payload" errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d retry Two issues caused --verify to always fail: 1. HMAC encoding mismatch: the agent returns HMAC as hex (matching Python's do_hmac hexdigest), but we compared against base64-encoded HMAC. Changed to hex::encode. 2. No retry: the agent needs V from the verifier before it can compute K = U XOR V. The Python tenant retries in a loop; we did a single attempt. Added exponential backoff retry (up to 12 attempts). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add animated progress spinners using indicatif for long-running operations (attestation polling, key derivation retry) and optional color output via console. Spinners auto-detect TTY on stderr and fall back to plain text when piped. Colors apply to stderr only, keeping stdout clean for machine consumption. New --color flag (auto|always|never) controls color output. The OutputHandler now supports start_wait() which returns an RAII WaitHandle for polling loops with live status updates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the agent's self-signed mTLS certificate (from the registrar database) as a trusted root CA when connecting to agents in pull mode. This allows verifying the agent's TLS certificate without disabling certificate verification globally, matching the Python tenant behavior. Also change accept_invalid_hostnames default from true to false, since certificates should have proper SANs set. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Disclaimer: this is an AI generated rewrite. We should be careful reviewing it.
Adds a modern Rust replacement for keylime_tenant with full API compatibility and improved usability.
Features
Implementation
Usage