Skip to content
Open
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
43 changes: 38 additions & 5 deletions crates/cli/src/commands/alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize};

use crate::exit_code::ExitCode;
use crate::output::{Formatter, OutputConfig};
use crate::secret_input::{SecretSource, can_prompt, read_code_interactive};
use rc_core::{Alias, AliasManager, Error, ObjectStore as _, validate_alias_endpoint};
use rc_s3::S3Client;

Expand Down Expand Up @@ -43,10 +44,10 @@ pub struct SetArgs {
/// S3 endpoint URL (e.g., `http://localhost:9000`, `https://s3.amazonaws.com`)
pub endpoint: String,

/// Access key ID (omit with --anonymous)
/// Access key ID (prompted on a terminal when omitted; omit with --anonymous)
pub access_key: Option<String>,

/// Secret access key (omit with --anonymous)
/// Secret access key (prompted on a terminal when omitted; omit with --anonymous)
pub secret_key: Option<String>,

/// Send requests without SigV4 credentials
Expand Down Expand Up @@ -236,7 +237,7 @@ pub async fn execute(cmd: AliasCommands, output_config: OutputConfig) -> ExitCod
}
}

async fn execute_set(args: SetArgs, manager: &AliasManager, formatter: &Formatter) -> ExitCode {
async fn execute_set(mut args: SetArgs, manager: &AliasManager, formatter: &Formatter) -> ExitCode {
// Validate inputs
if args.name.is_empty() {
return formatter.fail(ExitCode::UsageError, "Alias name cannot be empty");
Expand All @@ -257,11 +258,11 @@ async fn execute_set(args: SetArgs, manager: &AliasManager, formatter: &Formatte
);
}

let has_access_key = args
let mut has_access_key = args
.access_key
.as_ref()
.is_some_and(|value| !value.is_empty());
let has_secret_key = args
let mut has_secret_key = args
.secret_key
.as_ref()
.is_some_and(|value| !value.is_empty());
Expand All @@ -273,6 +274,38 @@ async fn execute_set(args: SetArgs, manager: &AliasManager, formatter: &Formatte
);
}

// Prompt for missing keys only on a terminal, so scripts and --json keep
// failing fast instead of hanging. This keeps the keys out of shell history.
if !args.anonymous && (!has_access_key || !has_secret_key) && can_prompt(formatter.is_json()) {
if !has_access_key {
match read_code_interactive("Enter Access Key: ") {
Ok(value) if !value.is_empty() => {
args.access_key = Some(value.to_string());
has_access_key = true;
}
Ok(_) => {}
Err(e) => {
let code = exit_code_from_error(&e);
formatter.error_with_code(code, &e.to_string());
return code;
}
}
}
if !has_secret_key {
match SecretSource::Prompt.load("Enter Secret Key: ") {
Ok(value) => {
args.secret_key = Some(value.to_string());
has_secret_key = true;
}
Err(e) => {
let code = exit_code_from_error(&e);
formatter.error_with_code(code, &e.to_string());
return code;
}
}
}
}

if !args.anonymous && (!has_access_key || !has_secret_key) {
return formatter.fail(
ExitCode::UsageError,
Expand Down
14 changes: 11 additions & 3 deletions docs/reference/rc/alias.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The `rc alias` operation manages named S3-compatible service endpoints in the lo

```bash
rc [GLOBAL OPTIONS] alias <COMMAND>
rc [GLOBAL OPTIONS] alias set [OPTIONS] <NAME> <ENDPOINT> <ACCESS_KEY> <SECRET_KEY>
rc [GLOBAL OPTIONS] alias set [OPTIONS] <NAME> <ENDPOINT> [ACCESS_KEY] [SECRET_KEY]
rc [GLOBAL OPTIONS] alias list [-l|--long]
rc [GLOBAL OPTIONS] alias remove <NAME>
rc [GLOBAL OPTIONS] alias export [NAMES]... [--output <FILE>] [--include-credentials --acknowledge-credentials]
Expand All @@ -31,8 +31,8 @@ rc [GLOBAL OPTIONS] alias import <FILE> [--replace]
| --- | --- |
| `NAME` | Local alias name, such as `local`, `s3`, or `rustfs`. |
| `ENDPOINT` | S3-compatible endpoint URL, such as `http://localhost:9000`. |
| `ACCESS_KEY` | Access key ID for the endpoint. |
| `SECRET_KEY` | Secret access key for the endpoint. |
| `ACCESS_KEY` | Access key ID for the endpoint. Prompted on a terminal when omitted. |
| `SECRET_KEY` | Secret access key for the endpoint. Prompted with hidden input on a terminal when omitted. |
| `--region` | AWS region to associate with the alias. Defaults to `us-east-1`. |
| `--signature` | Signature version, `v4` or `v2`. Defaults to `v4`. |
| `--bucket-lookup` | Bucket lookup style: `auto`, `path`, or `dns`. Defaults to `auto`. |
Expand All @@ -52,6 +52,14 @@ Configure a local RustFS or MinIO-compatible service:
rc alias set local http://localhost:9000 ACCESS_KEY SECRET_KEY
```

Omit the keys on a terminal to be prompted instead of typing them into the shell, where they would be saved in history:

```bash
rc alias set local http://localhost:9000
```

When stdin is not a terminal, or when `--json` is set, the keys are required on the command line.

Configure AWS S3 with an explicit region:

```bash
Expand Down