feat(iam): add SetUserStatus and UpdateAccessKey actions (#7750)

feat(iam): add SetUserStatus and UpdateAccessKey actions (#7745)

Add ability to enable/disable users and access keys without deleting them.

## Changes

### Protocol Buffer Updates
- Add `disabled` field (bool) to Identity message for user status
  - false (default) = enabled, true = disabled
  - No backward compatibility hack needed since zero value is correct
- Add `status` field (string: Active/Inactive) to Credential message

### New IAM Actions
- SetUserStatus: Enable or disable a user (requires admin)
- UpdateAccessKey: Change access key status (self-service or admin)

### Behavior
- Disabled users: All API requests return AccessDenied
- Inactive access keys: Signature validation fails
- Status check happens early in auth flow for performance
- Backward compatible: existing configs default to enabled (disabled=false)

### Use Cases
1. Temporary suspension: Disable user access during investigation
2. Key rotation: Deactivate old key before deletion
3. Offboarding: Disable rather than delete for audit purposes
4. Emergency response: Quickly disable compromised credentials

Fixes #7745
This commit is contained in:
Chris Lu
2025-12-14 18:48:39 -08:00
committed by GitHub
parent 7ed7578424
commit f64ce759e0
9 changed files with 647 additions and 19 deletions

View File

@@ -190,7 +190,7 @@ func mustNewRequest(method string, urlStr string, contentLength int64, body io.R
// is signed with AWS Signature V4, fails if not able to do so.
func mustNewSignedRequest(method string, urlStr string, contentLength int64, body io.ReadSeeker, t *testing.T) *http.Request {
req := mustNewRequest(method, urlStr, contentLength, body, t)
cred := &Credential{"access_key_1", "secret_key_1"}
cred := &Credential{AccessKey: "access_key_1", SecretKey: "secret_key_1"}
if err := signRequestV4(req, cred.AccessKey, cred.SecretKey); err != nil {
t.Fatalf("Unable to initialized new signed http request %s", err)
}
@@ -201,7 +201,7 @@ func mustNewSignedRequest(method string, urlStr string, contentLength int64, bod
// is presigned with AWS Signature V4, fails if not able to do so.
func mustNewPresignedRequest(iam *IdentityAccessManagement, method string, urlStr string, contentLength int64, body io.ReadSeeker, t *testing.T) *http.Request {
req := mustNewRequest(method, urlStr, contentLength, body, t)
cred := &Credential{"access_key_1", "secret_key_1"}
cred := &Credential{AccessKey: "access_key_1", SecretKey: "secret_key_1"}
if err := preSignV4(iam, req, cred.AccessKey, cred.SecretKey, int64(10*time.Minute.Seconds())); err != nil {
t.Fatalf("Unable to initialized new signed http request %s", err)
}