Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions crates/auths-cli/src/commands/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,13 @@ pub enum AgentSubcommand {
/// Unlock the agent (re-load keys)
Unlock {
/// Key alias to unlock
#[arg(long, default_value = "default", help = "Key alias to unlock")]
key: String,
#[arg(
long = "agent-key-alias",
visible_alias = "key",
default_value = "default",
help = "Key alias to unlock"
)]
agent_key_alias: String,
},

/// Install as a system service (launchd on macOS, systemd on Linux)
Expand Down Expand Up @@ -177,7 +182,7 @@ pub fn handle_agent(cmd: AgentCommand) -> Result<()> {
AgentSubcommand::Status => show_status(),
AgentSubcommand::Env { shell } => output_env(shell),
AgentSubcommand::Lock => lock_agent(),
AgentSubcommand::Unlock { key } => unlock_agent(&key),
AgentSubcommand::Unlock { agent_key_alias } => unlock_agent(&agent_key_alias),
AgentSubcommand::InstallService {
dry_run,
force,
Expand Down
9 changes: 7 additions & 2 deletions crates/auths-cli/src/commands/artifact/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,21 @@ pub enum ArtifactSubcommand {
/// Local alias of the identity key (used for signing). Omit for CI device-only signing.
#[arg(
long,
visible_alias = "ika",
help = "Local alias of the identity key. Omit for device-only CI signing."
)]
identity_key_alias: Option<String>,

/// Local alias of the device key (used for dual-signing).
#[arg(long, help = "Local alias of the device key (used for dual-signing).")]
#[arg(
long,
visible_alias = "dka",
help = "Local alias of the device key (used for dual-signing)."
)]
device_key_alias: String,

/// Number of days until the signature expires.
#[arg(long, value_name = "N")]
#[arg(long, visible_alias = "days", value_name = "N")]
expires_in_days: Option<i64>,

/// Optional note to embed in the attestation.
Expand Down
38 changes: 30 additions & 8 deletions crates/auths-cli/src/commands/device/authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,23 @@ pub enum DeviceSubcommand {
/// Authorize a new device to act on behalf of the identity.
#[command(visible_alias = "add")]
Link {
#[arg(long, help = "Local alias of the *identity's* key (used for signing).")]
#[arg(
long,
visible_alias = "ika",
help = "Local alias of the *identity's* key (used for signing)."
)]
identity_key_alias: String,

#[arg(
long,
visible_alias = "dka",
help = "Local alias of the *new device's* key (must be imported first)."
)]
device_key_alias: String,

#[arg(
long,
visible_alias = "device",
help = "Identity ID of the new device being authorized (must match device-key-alias)."
)]
device_did: String,
Expand All @@ -111,6 +117,7 @@ pub enum DeviceSubcommand {

#[arg(
long,
visible_alias = "days",
value_name = "DAYS",
help = "Optional number of days until this device authorization expires."
)]
Expand All @@ -132,7 +139,11 @@ pub enum DeviceSubcommand {

/// Revoke an existing device authorization using the identity key.
Revoke {
#[arg(long, help = "Identity ID of the device authorization to revoke.")]
#[arg(
long,
visible_alias = "device",
help = "Identity ID of the device authorization to revoke."
)]
device_did: String,

#[arg(
Expand All @@ -147,7 +158,11 @@ pub enum DeviceSubcommand {

/// Resolve a device DID to its controller identity DID.
Resolve {
#[arg(long, help = "The device DID to resolve (e.g. did:key:z6Mk...).")]
#[arg(
long,
visible_alias = "device",
help = "The device DID to resolve (e.g. did:key:z6Mk...)."
)]
device_did: String,
},

Expand All @@ -160,24 +175,31 @@ pub enum DeviceSubcommand {

/// Extend the expiration date of an existing device authorization.
Extend {
#[arg(long, help = "Identity ID of the device authorization to extend.")]
#[arg(
long,
visible_alias = "device",
help = "Identity ID of the device authorization to extend."
)]
device_did: String,

#[arg(
long,
long = "expires-in-days",
visible_alias = "days",
value_name = "DAYS",
help = "Number of days to extend the expiration by (from now)."
)]
days: i64,
expires_in_days: i64,

#[arg(
long = "identity-key-alias",
visible_alias = "ika",
help = "Local alias of the *identity's* key (required for re-signing)."
)]
identity_key_alias: String,

#[arg(
long = "device-key-alias",
visible_alias = "dka",
help = "Local alias of the *device's* key (required for re-signing)."
)]
device_key_alias: String,
Expand Down Expand Up @@ -297,14 +319,14 @@ pub fn handle_device(

DeviceSubcommand::Extend {
device_did,
days,
expires_in_days,
identity_key_alias,
device_key_alias,
} => handle_extend(
&repo_path,
&config,
&device_did,
days,
expires_in_days,
&identity_key_alias,
&device_key_alias,
passphrase_provider,
Expand Down
19 changes: 12 additions & 7 deletions crates/auths-cli/src/commands/device/pair/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,14 @@ pub struct PairCommand {
#[clap(long)]
pub no_qr: bool,

/// Custom expiry time in seconds (default: 300 = 5 minutes)
#[clap(long, value_name = "SECONDS", default_value = "300")]
pub expiry: u64,
/// Custom timeout in seconds for the pairing session (default: 300 = 5 minutes)
#[clap(
long,
visible_alias = "expiry",
value_name = "SECONDS",
default_value = "300"
)]
pub timeout: u64,

/// Skip registry server (offline mode, for testing)
#[clap(long)]
Expand Down Expand Up @@ -72,7 +77,7 @@ pub fn handle_pair(
match (&cmd.join, &cmd.registry, cmd.offline) {
// Offline mode takes priority
(None, _, true) => {
offline::handle_initiate_offline(cmd.no_qr, cmd.expiry, &cmd.capabilities)
offline::handle_initiate_offline(cmd.no_qr, cmd.timeout, &cmd.capabilities)
}

// Join with explicit registry -> online join
Expand Down Expand Up @@ -102,7 +107,7 @@ pub fn handle_pair(
http_client,
registry,
cmd.no_qr,
cmd.expiry,
cmd.timeout,
&cmd.capabilities,
env_config,
))
Expand All @@ -115,7 +120,7 @@ pub fn handle_pair(
rt.block_on(lan::handle_initiate_lan(
cmd.no_qr,
cmd.no_mdns,
cmd.expiry,
cmd.timeout,
&cmd.capabilities,
env_config,
))
Expand All @@ -129,7 +134,7 @@ pub fn handle_pair(
http_client,
DEFAULT_REGISTRY,
cmd.no_qr,
cmd.expiry,
cmd.timeout,
&cmd.capabilities,
env_config,
))
Expand Down
2 changes: 1 addition & 1 deletion crates/auths-cli/src/commands/device/verify_attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub struct VerifyCommand {
///
/// Looks up the public key from pinned identity store or roots.json.
/// Uses --trust policy to determine behavior for unknown identities.
#[arg(long = "issuer-did", value_parser)]
#[arg(long = "issuer-did", visible_alias = "issuer", value_parser)]
pub issuer_did: Option<String>,

/// Trust policy for unknown identities.
Expand Down
2 changes: 1 addition & 1 deletion crates/auths-cli/src/commands/emergency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ pub struct ReportCommand {
pub events: usize,

/// Output file path (defaults to stdout).
#[arg(long = "file", short = 'o')]
#[arg(long = "output", visible_alias = "file", short = 'o')]
pub output_file: Option<PathBuf>,

/// Path to the Auths repository.
Expand Down
21 changes: 13 additions & 8 deletions crates/auths-cli/src/commands/id/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,10 @@ pub enum IdSubcommand {
alias: String,

/// Output file path for the JSON bundle.
#[arg(long, short, help = "Output file path")]
output: PathBuf,
// Named `output_file` because the top-level `Cli` has a global `--output`
// (OutputFormat) arg; clap panics on the field-name collision.
#[arg(long = "output", short = 'o')]
output_file: PathBuf,

/// TTL in seconds. The bundle will fail verification after this many seconds.
#[arg(
Expand Down Expand Up @@ -517,13 +519,13 @@ pub fn handle_id(

IdSubcommand::ExportBundle {
alias,
output,
output_file,
max_age_secs,
} => {
println!("📦 Exporting identity bundle...");
println!(" Using Repository: {:?}", repo_path);
println!(" Key Alias: {}", alias);
println!(" Output File: {:?}", output);
println!(" Output File: {:?}", output_file);

// Load identity
let identity_storage = RegistryIdentityStorage::new(repo_path.clone());
Expand Down Expand Up @@ -565,14 +567,17 @@ pub fn handle_id(
// Write to output file
let json = serde_json::to_string_pretty(&bundle)
.context("Failed to serialize identity bundle")?;
fs::write(&output, &json)
.with_context(|| format!("Failed to write bundle to {:?}", output))?;
fs::write(&output_file, &json)
.with_context(|| format!("Failed to write bundle to {:?}", output_file))?;

println!("\n✅ Identity bundle exported successfully!");
println!(" Output: {:?}", output);
println!(" Output: {:?}", output_file);
println!(" Attestations: {}", bundle.attestation_chain.len());
println!("\nUsage in CI:");
println!(" auths verify-commit --identity-bundle {:?} HEAD", output);
println!(
" auths verify-commit --identity-bundle {:?} HEAD",
output_file
);

Ok(())
}
Expand Down
42 changes: 27 additions & 15 deletions crates/auths-cli/src/commands/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@ pub enum KeySubcommand {
/// Export a stored key in various formats (requires passphrase for some formats).
Export {
/// Local alias of the key to export.
#[arg(long, help = "Local alias of the key to export.")]
alias: String,
#[arg(
long = "key-alias",
visible_alias = "alias",
help = "Local alias of the key to export."
)]
key_alias: String,

/// Passphrase to decrypt the key (needed for 'pem'/'pub' formats).
#[arg(
Expand All @@ -53,15 +57,23 @@ pub enum KeySubcommand {
/// Remove a key from the platform's secure storage by alias.
Delete {
/// Local alias of the key to remove.
#[arg(long, help = "Local alias of the key to remove.")]
alias: String,
#[arg(
long = "key-alias",
visible_alias = "alias",
help = "Local alias of the key to remove."
)]
key_alias: String,
},

/// Import an Ed25519 key from a 32-byte seed file and store it encrypted.
Import {
/// Local alias to assign to the imported key.
#[arg(long, help = "Local alias to assign to the imported key.")]
alias: String,
#[arg(
long = "key-alias",
visible_alias = "alias",
help = "Local alias to assign to the imported key."
)]
key_alias: String,

/// Path to the file containing the raw 32-byte Ed25519 seed.
#[arg(
Expand Down Expand Up @@ -96,8 +108,8 @@ pub enum KeySubcommand {
/// --dst-backend file --dst-file /tmp/ci-keychain.enc --dst-passphrase "$CI_PASS"
CopyBackend {
/// Alias of the key to copy from the current (source) keychain.
#[arg(long)]
alias: String,
#[arg(long = "key-alias", visible_alias = "alias")]
key_alias: String,

/// Destination backend type. Currently supported: "file".
#[arg(long)]
Expand All @@ -118,26 +130,26 @@ pub fn handle_key(cmd: KeyCommand) -> Result<()> {
match cmd.command {
KeySubcommand::List => key_list(),
KeySubcommand::Export {
alias,
key_alias,
passphrase,
format,
} => key_export(&alias, &passphrase, format),
KeySubcommand::Delete { alias } => key_delete(&alias),
} => key_export(&key_alias, &passphrase, format),
KeySubcommand::Delete { key_alias } => key_delete(&key_alias),
KeySubcommand::Import {
alias,
key_alias,
seed_file,
controller_did,
} => {
let identity_did = IdentityDID::new(controller_did);
key_import(&alias, &seed_file, &identity_did)
key_import(&key_alias, &seed_file, &identity_did)
}
KeySubcommand::CopyBackend {
alias,
key_alias,
dst_backend,
dst_file,
dst_passphrase,
} => key_copy_backend(
&alias,
&key_alias,
&dst_backend,
dst_file.as_ref(),
dst_passphrase.as_deref(),
Expand Down
Loading
Loading