mirror of
https://github.com/pgsty/minio.git
synced 2026-09-11 13:04:03 +03:00
docs(iam): explain breaking password-policy semantics
Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
# Password and user-management permissions
|
||||
|
||||
**Breaking change: the password-permission split changes the meaning of
|
||||
existing IAM policies.** The same stored policy can authorize a request after
|
||||
this update that it denied before, or deny a request it previously authorized.
|
||||
This is a deliberate authorization change from adopting
|
||||
[minio/pkg #262](https://github.com/minio/pkg/pull/262), independent of the
|
||||
minio-go SDK update. It must be called out as a breaking change in the release
|
||||
that first includes it; it is not a transparent dependency refresh.
|
||||
|
||||
SILO separates a user's own password change from creating users or resetting
|
||||
another user's password. The same `add-user` administration endpoint and mcli
|
||||
commands continue to work; the authenticated caller and target access key
|
||||
@@ -16,52 +24,119 @@ still requires the current password. STS and service-account credentials cannot
|
||||
change their parent user's password; root credentials and external identity
|
||||
provider passwords remain outside this endpoint.
|
||||
|
||||
## Existing policies
|
||||
## What changes and why
|
||||
|
||||
Previously, both operations checked `admin:CreateUser`. Changing one's own
|
||||
password used an implicit grant unless that action was explicitly denied;
|
||||
managing other users required an explicit Allow. The split retains these two
|
||||
evaluation rules but checks `admin:ChangeMyPassword` for the caller's password.
|
||||
It lets an operator independently control password changes and user
|
||||
administration. This is a policy-design choice, not a required mitigation for
|
||||
the SDK signing or region-compatibility fixes.
|
||||
|
||||
The following cases assume an internal user with an attached policy, matching
|
||||
statement conditions, and no other applicable grants or denies:
|
||||
|
||||
| Existing policy | Own password before | Own password after | Create/reset another user, before and after |
|
||||
| --- | --- | --- | --- |
|
||||
| S3 read grant only | Allowed | Allowed | Denied |
|
||||
| `Deny admin:CreateUser` | Denied | **Allowed** | Denied |
|
||||
| `Deny admin:ChangeMyPassword` | Allowed | **Denied** | Denied |
|
||||
| `Allow admin:CreateUser` | Allowed | Allowed | Allowed |
|
||||
| `Allow admin:CreateUser` plus `Deny admin:ChangeMyPassword` | Allowed | **Denied** | Allowed |
|
||||
| Deny both actions, or `Deny admin:*` | Denied | Denied | Denied |
|
||||
|
||||
Wildcard denies that match `admin:CreateUser` but do not match
|
||||
`admin:ChangeMyPassword`, such as `admin:Create*`, have the same password
|
||||
compatibility change as the explicit CreateUser deny. An Allow never overrides
|
||||
a matching Deny. Granting only `admin:ChangeMyPassword` does not grant user
|
||||
administration.
|
||||
|
||||
The policy JSON format, stored documents and endpoint are retained, but that
|
||||
does not preserve their authorization semantics. This update does not rewrite
|
||||
saved policies or provide a switch that restores the old action mapping.
|
||||
|
||||
## Preserve the behavior of existing policies
|
||||
|
||||
A saved `Deny admin:CreateUser` still prevents user creation and password resets
|
||||
for other users. It no longer prevents the caller from changing their own
|
||||
password. If an existing policy used that deny to lock the caller's password,
|
||||
add the new action to the same Deny statement before upgrading:
|
||||
add `admin:ChangeMyPassword` to the **same Deny statement before upgrading**.
|
||||
For example, change that statement's action list to:
|
||||
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Deny",
|
||||
"Action": ["admin:CreateUser", "admin:ChangeMyPassword"]
|
||||
}
|
||||
]
|
||||
"Effect": "Deny",
|
||||
"Action": ["admin:CreateUser", "admin:ChangeMyPassword"]
|
||||
}
|
||||
```
|
||||
|
||||
Preserve any existing conditions on that statement. To lock only the caller's
|
||||
password while allowing separately granted user administration, deny only
|
||||
`admin:ChangeMyPassword`. An existing `Deny admin:*` denies both actions.
|
||||
An Allow cannot override a matching Deny.
|
||||
This is a statement fragment, not a replacement for the entire policy.
|
||||
Preserve its other actions, resource scope and conditions, and all other
|
||||
statements. Check policies attached through groups as well as directly to users.
|
||||
The preceding SILO package version already recognizes both action names, so
|
||||
this dual deny can be prepared before the Server upgrade. Saved policy files
|
||||
are not migrated automatically; the operator must apply this change where the
|
||||
old password restriction is intended.
|
||||
|
||||
To adopt the new split and lock only the caller's password while allowing
|
||||
separately granted user administration, deny only `admin:ChangeMyPassword`.
|
||||
That finer distinction is enforced only by Servers containing this change.
|
||||
|
||||
## Built-in read-only policies
|
||||
|
||||
The built-in `readonly` policy now grants its original S3 read operations
|
||||
without a CreateUser deny. The added `consolereadonly` policy also grants
|
||||
ListBucket for Console browsing. Neither grants user administration or S3
|
||||
writes. Both permit self-service password changes unless another policy denies
|
||||
them. Combining either read-only policy with an explicit CreateUser Allow is
|
||||
supported.
|
||||
without its previous CreateUser deny. This has two compatibility effects:
|
||||
|
||||
- A user of the old `readonly` policy could not change their own password; with
|
||||
the split they can, unless another applicable statement denies
|
||||
`admin:ChangeMyPassword`.
|
||||
- The old built-in `readonly` deny overrode a separate CreateUser Allow. The
|
||||
new built-in definition allows that independently granted user administration.
|
||||
This can broaden effective permissions for users with both policies attached.
|
||||
|
||||
The added `consolereadonly` policy also grants ListBucket for Console browsing
|
||||
and follows the new split. Neither read-only policy grants user administration
|
||||
or S3 writes on its own. Their S3 permissions do not implicitly lock passwords.
|
||||
|
||||
Saved policies and user overrides of canned policies are preserved on upgrade.
|
||||
A saved copy of the old read-only policy therefore retains its CreateUser deny:
|
||||
it still blocks a separate CreateUser Allow, even though self-service password
|
||||
changes now use the new action. Review that deny explicitly if combining old
|
||||
read-only policies with user-administration grants.
|
||||
A saved copy of the old read-only policy retains its CreateUser deny and still
|
||||
blocks a separate CreateUser Allow, even though it no longer blocks self-service
|
||||
password changes. Where no saved override exists, Server uses the updated
|
||||
built-in definition. Review the effective policy documents rather than assuming
|
||||
every policy named `readonly` has the same contents. To retain both old
|
||||
restrictions, attach a policy denying both actions or retain the saved readonly
|
||||
override and add ChangeMyPassword to its existing deny.
|
||||
|
||||
## Coordinated upgrade
|
||||
## Console and package callers
|
||||
|
||||
`silo-pkg`'s `Policy.IsAllowedActions` now reports `admin:ChangeMyPassword` as
|
||||
implicit unless denied, and reports `admin:CreateUser` only when explicitly
|
||||
allowed. Its Go signature and the Go compatibility floor are unchanged, but
|
||||
its returned capabilities change. Console and other consumers must stop using
|
||||
the CreateUser capability as a proxy for permission to change one's own password.
|
||||
|
||||
## Coordinated upgrade and rollback
|
||||
|
||||
Upgrade SILO Server, silo-pkg and Console together, including the Console
|
||||
embedded in Server. Update mcli's shared package and SDK pins as part of the
|
||||
same maintained stack. Mixed versions disagree about the self-service action
|
||||
and may show a button the Server refuses, hide an allowed operation, or fail to
|
||||
enforce a new password-specific deny on an old Server. Complete a rolling
|
||||
Server upgrade before relying on the new permission split.
|
||||
enforce a new password-specific deny on an old Server.
|
||||
|
||||
This adopts [minio/pkg #262](https://github.com/minio/pkg/pull/262). Upstream
|
||||
MinIO compatibility remains best effort; the supported integration target is
|
||||
`pgsty/silo`.
|
||||
Before upgrading, export the affected user/group policy documents, review the
|
||||
cases above, and apply both denies wherever the old combined restriction must
|
||||
survive. Keep both denies throughout a rolling upgrade and any rollback window.
|
||||
Verify self-service password changes and other-user creation/password resets
|
||||
with the affected accounts. Complete the Server rollout and update Console
|
||||
before relying on the new independent permissions.
|
||||
|
||||
Rolling back the binaries does not convert policies. An old Server ignores
|
||||
`Deny admin:ChangeMyPassword` for this endpoint, so that deny alone cannot lock
|
||||
the password after rollback. Restore or retain the CreateUser deny when the
|
||||
password must remain locked; on the old Server it will also deny management of
|
||||
other users. The old Server cannot represent the new combination of allowing
|
||||
user administration while denying only self-service password changes.
|
||||
|
||||
Upstream MinIO compatibility remains best effort; the supported integration
|
||||
target is `pgsty/silo`.
|
||||
|
||||
Reference in New Issue
Block a user