* shell: accept ReadAcp and WriteAcp in per-bucket and service account actions
s3.bucket.access, s3.anonymous.set and s3.serviceaccount.create rejected
ReadAcp and WriteAcp, so the ACL actions the S3 gateway enforces could not
be granted through them. Share one canonical action table across the
three commands and list the ACL actions in their help.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* shell: list ReadAcp and WriteAcp in s3.configure and s3.circuitBreaker help
The -actions usage of both commands stopped at Admin, so the ACL actions
the gateway enforces could only be found in the source. s3.circuitBreaker
now prints the actions it actually accepts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: offer ReadAcp and WriteAcp in the object store user permissions
The create and edit user forms only offered Read, Write, List, Tagging and
Admin among the bucket permissions, so an identity could not be given the
ACL actions from the UI even though uploads with x-amz-acl need WriteAcp.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: log the WriteAcp denial of an upload that sets an ACL
An upload or copy that carries x-amz-acl or an x-amz-grant-* header also
needs WriteAcp. When that check denies, the client only sees a bare
AccessDenied and nothing reached the log at the default verbosity, so
the header was never suspected. Log the identity and the missing action.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: quote the key in the ACL upload denial log
An object key can carry a decoded newline, which let a caller add forged
lines to the default log. Quote the bucket and key, and word the message
so it also fits a policy deny, not only a missing grant.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* shell: say ACL uploads need both Write and WriteAcp
The s3.configure example granted WriteAcp alone, which still fails the
upload's Write check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* shell: parse S3 action lists with one shared helper
s3.bucket.access, s3.anonymous.set and s3.serviceaccount.create each had
their own validation loop, so a test of the table did not cover the
parsing the commands run. They now call canonicalActionList, which skips
empty entries and repeats. s3.anonymous.set validates before contacting
IAM, and s3.bucket.access still rejects a list with no actions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: keep bucket-scoped actions the user form cannot show
When a user has both global and bucket-scoped actions, the edit form
shows only the global ones, and saving replaced the identity's actions
with what the form rebuilt, deleting the scoped grants. Carry those
actions through the save.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: list hidden bucket grants in the user edit form
Restoring the bucket-scoped grants the form cannot show kept them active
even when an admin narrowed the user's permissions, with no way to see
or drop them. Show them as checked boxes under Other Bucket Permissions;
unchecking one removes it on save.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* shell: reject an s3.anonymous.set -access list with no actions
A blank list such as ",," parsed to nothing and cleared the bucket's
anonymous grants. Use "none" for that, as s3.bucket.access does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: skip the ACL upload denial log for anonymous requests
Anonymous uploads with ACL headers can be sent by anyone, so logging
each denial at the default level lets unauthenticated clients flood the
log. Keep the line for named identities.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: count kept bucket grants when checking an edited user for permissions
The empty check ran before the checked Other Bucket Permissions were
merged, so a user left with only those grants could not be saved.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: list bucket grants of Admin users in the user edit form
parseBucketPermissions returned before reading scoped actions when the
user had Admin, so removing Admin and saving dropped grants such as
WriteAcp:bucket.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: keep unpaired bucket grants as separate checkboxes in the user edit form
The form saves every selected permission on every selected bucket, so
grants such as ReadAcp:a with WriteAcp:b came back as all four pairs.
Show the grants through the picker only when they cover that full
product; otherwise list each grant on its own. Opening the form also
resets the bucket scope left over from the previous user.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: keep grants the edit pickers have no option for
A permission x bucket product was shown through the pickers even when a
bucket was not in the bucket list (deleted, prefix or wildcard grants)
or a permission had no picker option (DeleteBucket, PutBucketQuota).
Saving then dropped those grants. Such grants now go to the checkbox
list, global ones included, and are submitted unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* shell: name the s3.bucket.access anonymous example by what it grants
Read,Write,List leaves out ReadAcp and WriteAcp, so it is not full
access.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: keep unlisted global grants of Admin users in the user edit form
parseBucketPermissions returned for Admin before splitting global grants
into picker options and the rest, and only raw option values were
re-selected. Saving an Admin user dropped s3tables:* and grants with no
picker option such as DeleteBucket. Admin users now use the same split.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* admin: keep the /* suffix of bucket grants in the user edit form
parseBucketPermissions dropped a trailing /* before matching bucket
options, so saving rewrote ReadAcp:bucket/* as ReadAcp:bucket. The bare
form also matches bucket-level requests such as GET ?acl, so the save
widened the grant. A /* bucket is not a picker option, so the grant now
stays in the checkbox list as written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* shell: test that s3.bucket.access saves ReadAcp and WriteAcp grants
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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
* Fix master leader election startup issue
Fixes #error-log-leader-not-selected-yet
* not useful test
* fix(iam): ensure access key status is persisted and defaulted to Active
* make pb
* update tests
* using constants
* Add IAM gRPC service definition
- Add GetConfiguration/PutConfiguration for config management
- Add CreateUser/GetUser/UpdateUser/DeleteUser/ListUsers for user management
- Add CreateAccessKey/DeleteAccessKey/GetUserByAccessKey for access key management
- Methods mirror existing IAM HTTP API functionality
* Add IAM gRPC handlers on filer server
- Implement IamGrpcServer with CredentialManager integration
- Handle configuration get/put operations
- Handle user CRUD operations
- Handle access key create/delete operations
- All methods delegate to CredentialManager for actual storage
* Wire IAM gRPC service to filer server
- Add CredentialManager field to FilerOption and FilerServer
- Import credential store implementations in filer command
- Initialize CredentialManager from credential.toml if available
- Register IAM gRPC service on filer gRPC server
- Enable credential management via gRPC alongside existing filer services
* Regenerate IAM protobuf with gRPC service methods
* iam_pb: add Policy Management to protobuf definitions
* credential: implement PolicyManager in credential stores
* filer: implement IAM Policy Management RPCs
* shell: add s3.policy command
* test: add integration test for s3.policy
* test: fix compilation errors in policy_test
* pb
* fmt
* test
* weed shell: add -policies flag to s3.configure
This allows linking/unlinking IAM policies to/from identities
directly from the s3.configure command.
* test: verify s3.configure policy linking and fix port allocation
- Added test case for linking policies to users via s3.configure
- Implemented findAvailablePortPair to ensure HTTP and gRPC ports
are both available, avoiding conflicts with randomized port assignments.
- Updated assertion to match jsonpb output (policyNames)
* credential: add StoreTypeGrpc constant
* credential: add IAM gRPC store boilerplate
* credential: implement identity methods in gRPC store
* credential: implement policy methods in gRPC store
* admin: use gRPC credential store for AdminServer
This ensures that all IAM and policy changes made through the Admin UI
are persisted via the Filer's IAM gRPC service instead of direct file manipulation.
* shell: s3.configure use granular IAM gRPC APIs instead of full config patching
* shell: s3.configure use granular IAM gRPC APIs
* shell: replace deprecated ioutil with os in s3.policy
* filer: use gRPC FailedPrecondition for unconfigured credential manager
* test: improve s3.policy integration tests and fix error checks
* ci: add s3 policy shell integration tests to github workflow
* filer: fix LoadCredentialConfiguration error handling
* credential/grpc: propagate unmarshal errors in GetPolicies
* filer/grpc: improve error handling and validation
* shell: use gRPC status codes in s3.configure
* credential: document PutPolicy as create-or-replace
* credential/postgres: reuse CreatePolicy in PutPolicy to deduplicate logic
* shell: add timeout context and strictly enforce flags in s3.policy
* iam: standardize policy content field naming in gRPC and proto
* shell: extract slice helper functions in s3.configure
* filer: map credential store errors to gRPC status codes
* filer: add input validation for UpdateUser and CreateAccessKey
* iam: improve validation in policy and config handlers
* filer: ensure IAM service registration by defaulting credential manager
* credential: add GetStoreName method to manager
* test: verify policy deletion in integration test