When jwt.filer_signing.key is set, the filer's IamGrpcServer requires
a Bearer token on every IAM RPC. The shell's s3.* IAM commands dialed
without that header and failed with Unauthenticated. Route them through
a small helper that mints a token from the same key viper-loaded from
security.toml and appends it as outgoing metadata, matching the credential
grpc_store pattern.
* shell: add s3.iam.*, s3.config.show, s3.user.provision; hide legacy commands
Add import/export, configuration summary, and a convenience provisioning
command:
- s3.iam.export: dump full IAM state as JSON (stdout or file)
- s3.iam.import: replace IAM state from a JSON file
- s3.config.show: human-readable summary (users, policies, service
accounts, groups with status and counts)
- s3.user.provision: one-step user+policy+credentials creation for
common readonly/readwrite/admin roles
Hide legacy commands from help listing:
- s3.configure: still works but hidden from help output
- s3.bucket.access: still works but hidden from help output
Both hidden commands remain fully functional for existing scripts.
Also adds a Hidden command tag and filters it from printGenericHelp.
* shell: address review feedback for s3.iam.*, s3.config.show, s3.user.provision
- Simplify joinMax using strings.Join
- Fix rolePolicies: remove s3:ListBucket from object-level actions
(already covered by bucket-level statement)
- Fix admin role: grant s3:* on bucket resource too
- Return flag parse errors instead of swallowing them
* shell: address missed review feedback for PR 3
- s3.iam.import: require -force flag for destructive IAM overwrite
- s3.config.show: add nil guard for resp.Configuration
- s3.user.provision: check if user exists before creating policy
- s3.user.provision: reject wildcard bucket names (* ?)
* shell: distinguish NotFound from transient errors in provision, use %w wrapping
- s3.user.provision: check gRPC status code on GetUser error — only
proceed on NotFound, abort on transient/network errors
- s3.iam.import: use %w for error wrapping to preserve error chains,
wrap PutConfiguration error with context
* shell: remove duplicate joinMax after PR 8954 merge
command_s3_helpers.go defined joinMax which is already in
command_s3_user_list.go from the merged PR 8954.
* shell: restrict export file permissions, rollback policy on user create failure
- s3.iam.export: use os.OpenFile with mode 0600 instead of os.Create
to protect exported credentials from other users
- s3.user.provision: rollback the created policy if CreateUser fails,
with a warning if the rollback itself fails
* shell: add s3.bucket.access command for anonymous access policy (#7738)
Add a new weed shell command to view or change the anonymous access
policy of an S3 bucket without external tools.
Usage:
s3.bucket.access -name <bucket> -access read,list
s3.bucket.access -name <bucket> -access none
Supported permissions: read, write, list. The command writes a standard
bucket policy with Principal "*" and warns if no anonymous IAM identity
exists.
* shell: fix anonymous identity hint in s3.bucket.access warning
The anonymous identity doesn't need IAM actions — the bucket policy
controls what anonymous users can do.
* shell: only warn about anonymous identity when write access is set
Read and list operations use AuthWithPublicRead which evaluates bucket
policies directly without requiring the anonymous identity. Only write
operations go through the normal auth flow that needs it.
* shell: rewrite s3.bucket.access to use IAM actions instead of bucket policies
Replace the bucket policy approach with direct IAM identity actions,
matching the s3.configure pattern. The user is auto-created if it does
not exist.
Usage:
s3.bucket.access -name <bucket> -user anonymous -access Read,List
s3.bucket.access -name <bucket> -user anonymous -access none
s3.bucket.access -name <bucket> -user anonymous
Actions are stored as "Action:bucket" on the identity, same as
s3.configure -actions=Read -buckets=my-bucket.
* shell: return flag parse errors instead of swallowing them
* shell: normalize action names case-insensitively in s3.bucket.access
Accept actions in any case (read, READ, Read) and normalize to canonical
form (Read, Write, List, etc.) before storing. This matches the
case-insensitive handling of "none" and avoids confusing rejections.