Skip to content

feat(s3s-fs): read the access and secret key from the environment - #1014

Open
pmoust wants to merge 1 commit into
s3s-project:mainfrom
NOFireAI:feat/s3s-fs-credentials-env
Open

pmoust wants to merge 1 commit into
s3s-project:mainfrom
NOFireAI:feat/s3s-fs-credentials-env

Conversation

@pmoust

@pmoust pmoust commented Oct 25, 2026

Copy link
Copy Markdown

The s3s-fs binary takes its credentials only as --access-key and --secret-key. That puts the secret key in the process argument list, which any local user can read through ps or /proc.

With this change, both flags fall back to the environment variables S3S_FS_ACCESS_KEY and S3S_FS_SECRET_KEY. hide_env_values keeps their values out of --help. Nothing else about the flags changes:

  • A flag given on the command line still overrides the environment.
  • Giving only one of the pair is still an error.

The only build change is enabling clap's env feature on the crate's optional clap dependency, which adds no crates to the lock file.

This is separate from #1013, the listing fixes, so each can be reviewed on its own.

The s3s-fs binary took its credentials only as --access-key and
--secret-key, which puts the secret in the process argument list where
any local user can read it. Both flags now fall back to S3S_FS_ACCESS_KEY
and S3S_FS_SECRET_KEY, and --help does not print their values. The flags
still win when given, and giving only one of the pair is still an error.

Signed-off-by: Panagiotis Moustafellos <pmoust@nofire.ai>
Copilot AI balanced review requested due to automatic review settings October 25, 2026 20:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The narrow configuration changes preserve existing credential behavior, with no blocking issues identified.

No open issues 🎉

What changed in this PR

Adds environment-variable credentials to s3s-fs, allowing users to avoid exposing secrets in process arguments.

Changes:

  • Adds S3S_FS_ACCESS_KEY and S3S_FS_SECRET_KEY fallbacks while preserving command-line precedence and paired-credential validation.
  • Hides environment values from help output and enables clap’s env feature.
File Description
crates/​s3s-fs/​src/​main.rs Configures credential environment variables and hides their values in help.
crates/​s3s-fs/​Cargo.toml Enables environment support on the optional clap dependency.

Review effort: Balanced

pmoust added a commit to pmoust/ClickBench that referenced this pull request Oct 26, 2026
Ravel reads cold statements as ranged GETs. On a single drive RustFS
serves each ranged GET by reading the whole 1 MiB erasure block around
it, about 1.5 MB of disk per 10 KB range measured on c6a.4xlarge, so
the cold figures measured the store's read amplification more than the
database. s3s-fs serves a range with one file read. Both are
single-node S3 servers over the machine's disk; the entry stays a
local-disk entry with nothing required from the operator.

./install downloads the s3s-fs binary for the host architecture from a
release on the NOFireAI/s3s fork (s3s-fs-0.17.0-ravel.1: the v0.17.0
release plus listing ETags, s3s-project/s3s#1013, which Ravel's store
qualification requires, and keys read from the environment,
s3s-project/s3s#1014, so no key sits in a process argument list) and
verifies it against that release's SHA256SUMS before moving it into
place, the way Ravel's own binaries are installed. When the release is
unreachable it builds the same pinned commit with cargo install
--locked, so what runs is fixed by content either way; the commit
installed is recorded beside the binary. RustFS is gone from the entry:
nothing downloads it. rustfs-start becomes store-start, the store
directory is store/ and the generated keys are STORE_ACCESS_KEY and
STORE_SECRET_KEY.

The README gains a section on the store that states the swap and the
measured reason for it.
pmoust added a commit to pmoust/ClickBench that referenced this pull request Oct 26, 2026
Ravel reads cold statements as ranged GETs. On a single drive RustFS
serves each ranged GET by reading the whole 1 MiB erasure block around
it, about 1.5 MB of disk per 10 KB range measured on c6a.4xlarge, so
the cold figures measured the store's read amplification more than the
database. s3s-fs serves a range with one file read. Both are
single-node S3 servers over the machine's disk; the entry stays a
local-disk entry with nothing required from the operator.

./install downloads the s3s-fs binary for the host architecture from a
release on the NOFireAI/s3s fork (s3s-fs-0.17.0-ravel.1: the v0.17.0
release plus listing ETags, s3s-project/s3s#1013, which Ravel's store
qualification requires, and keys read from the environment,
s3s-project/s3s#1014, so no key sits in a process argument list) and
verifies it against that release's SHA256SUMS before moving it into
place, the way Ravel's own binaries are installed. When the release is
unreachable it builds the same pinned commit with cargo install
--locked, so what runs is fixed by content either way; the commit
installed is recorded beside the binary. RustFS is gone from the entry:
nothing downloads it. rustfs-start becomes store-start, the store
directory is store/ and the generated keys are STORE_ACCESS_KEY and
STORE_SECRET_KEY.

The README gains a section on the store that states the swap and the
measured reason for it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants