- Add PoolSize to LDAPConfig (default 10)
- Add Audience to LDAPConfig to align with OIDC validation
- Update initialization and ValidateToken to use new fields
- Move common logic for session claims and credential generation to prepareSTSCredentials
- Update handleAssumeRole and handleAssumeRoleWithLDAPIdentity to use the helper
- Remove stale comments referencing outdated line numbers
- Consistent with AWS, include the account ID in the assumed-role ARN
- Use the configured account ID from STS service if available, otherwise default to '111122223333'
- Apply to both AssumeRole and AssumeRoleWithLDAPIdentity handlers
- Also update .gitignore to ignore IAM test environment files
- Set Subject, Issuer, Audience, IssuedAt, and ExpiresAt to satisfy the interface
- Use time.Time for timestamps as required by TokenClaims struct
- Default to 1 hour TTL for LDAP tokens
- Add atomic 'closed' flag to connection pool to prevent racing on Close()
- Rebind authenticated user connections back to service account before returning to pool
- Close connections on error instead of returning potentially corrupted state to pool
The GitHub Actions workflow calls 'make setup' which was not creating
iam_config.json, causing the server to start without IAM integration
enabled (iamIntegration = nil), resulting in NotImplemented errors.
Now 'make setup' copies iam_config.local.json to iam_config.json if
it doesn't exist, ensuring IAM is properly configured in CI.
Updated s3_iam_distributed_test.go to use 'admin-user' and 'read-user'
which exist in the standard Keycloak setup provided by setup_keycloak.sh.
This resolves 'unknown test user' errors in distributed integration tests.
Following the change to make TokenGenerator public in STSService,
this commit updates the test files to reference the correct public field name.
This resolves compilation errors in the IAM STS test suite.
CRITICAL FIX:
- Make TokenGenerator public in STSService (was private tokenGenerator)
- Update all references from Config.TokenGenerator to TokenGenerator
- Remove TokenGenerator from STSConfig (it belongs in STSService)
This fixes the "NotImplemented" errors in distributed and Keycloak tests.
The issue was that Round 5 changes tried to access Config.TokenGenerator
which didn't exist - TokenGenerator is a field in STSService, not STSConfig.
The TokenGenerator is properly initialized in STSService.Initialize() and
is now accessible for JWT token generation in AssumeRole handlers.
PERFORMANCE IMPROVEMENT:
- Add connection pool to LDAPProvider (default size: 10 connections)
- Reuse LDAP connections across authentication requests
- Prevent file descriptor exhaustion under high load
IMPLEMENTATION:
- connectionPool struct with channel-based connection management
- getConnection(): retrieves from pool or creates new connection
- returnConnection(): returns healthy connections to pool
- createConnection(): establishes new LDAP connection with TLS support
- Close(): cleanup method to close all pooled connections
- Connection health checking (IsClosing()) before reuse
BENEFITS:
- Reduced connection overhead (no TCP handshake per request)
- Better resource utilization under load
- Prevents "too many open files" errors
- Non-blocking pool operations (creates new conn if pool empty)
- LDAP Provider Hardening:
- Prevent re-initialization
- Enforce single user match in `GetUserInfo` (was explicit only in Authenticate)
- Ensure connection closure if StartTLS fails
- STS Handlers:
- Add robust provider detection using type assertion
- **Security**: Implement authorization check (`VerifyActionPermission`) after LDAP authentication
- Routing:
- Update tests to reflect that STS actions are handled by STS handler, not generic IAM
- Improve `LDAPProvider` connection handling:
- Use `net.Dialer` with configured timeout for connection establishment
- Enforce TLS 1.2+ (`MinVersion: tls.VersionTLS12`) for both LDAPS and StartTLS
- Fix build error in `s3api_sts.go` (format verb for ErrorCode)
- Implement `validateLDAPConfig` in `ProviderFactory`
- Improve `LDAPProvider.Initialize`:
- Support `connectionTimeout` parsing (string/int/float) from config map
- Warn if `BindDN` is present but `BindPassword` is empty
- Improve `LDAPProvider.GetUserInfo`:
- Add fallback to `searchUserGroups` if `memberOf` returns no groups (consistent with Authenticate)
This commit addresses all critical security issues from PR review:
Security Fixes:
- Use crypto/rand for cryptographically secure credential generation
instead of time.Now().UnixNano() (fixes predictable credentials)
- Add sts:AssumeRole permission check via VerifyActionPermission to
prevent unauthorized role assumption
- Generate proper session tokens using crypto/rand instead of
placeholder strings
Code Quality Improvements:
- Refactor DurationSeconds parsing into reusable parseDurationSeconds()
helper function used by all three STS handlers
- Create generateSecureCredentials() helper for consistent and secure
temporary credential generation
- Fix iamMatcher to check query string as fallback when Action not
found in form data
LDAP Provider Implementation:
- Add go-ldap/ldap/v3 dependency
- Create LDAPProvider implementing IdentityProvider interface with
full LDAP authentication support (connect, bind, search, groups)
- Update ProviderFactory to create real LDAP providers
- Wire LDAP provider into AssumeRoleWithLDAPIdentity handler
Test Infrastructure:
- Add LDAP user creation verification step in setup_all_tests.sh
Update the IAM handler matcher to check for STS actions (AssumeRole,
AssumeRoleWithWebIdentity, AssumeRoleWithLDAPIdentity) and exclude them
from IAM handler processing. This allows STS requests to be handled by
the STS fallback handler even when they include AWS SigV4 authentication.
The matcher now parses the form data to check the Action parameter and
returns false for STS actions, ensuring they are routed to the correct
handler.
Note: This is a work-in-progress fix. Tests are still showing some
routing issues that need further investigation.
- Add s3_sts_assume_role_test.go with comprehensive tests for AssumeRole:
* Parameter validation (missing RoleArn, RoleSessionName, invalid duration)
* AWS SigV4 authentication with valid/invalid credentials
* Temporary credential generation and usage
- Add s3_sts_ldap_test.go with tests for AssumeRoleWithLDAPIdentity:
* Parameter validation (missing LDAP credentials, RoleArn)
* LDAP authentication scenarios (valid/invalid credentials)
* Integration with LDAP server (when configured)
- Update Makefile with new test targets:
* test-sts: run all STS tests
* test-sts-assume-role: run AssumeRole tests only
* test-sts-ldap: run LDAP STS tests only
* test-sts-suite: run tests with full service lifecycle
- Enhance setup_all_tests.sh:
* Add OpenLDAP container setup for LDAP testing
* Create test LDAP users (testuser, ldapadmin)
* Set LDAP environment variables for tests
* Update cleanup to remove LDAP container
- Fix setup_keycloak.sh:
* Enable verbose error logging for realm creation
* Improve error diagnostics
Tests use fail-fast approach (t.Fatal) when server not configured,
ensuring clear feedback when infrastructure is missing.
* Fix chown Input/output error on large file sets (Fixes#7911)
Implemented retry logic for MySQL/MariaDB backend to handle transient errors like deadlocks and timeouts.
* Fix syntax error: missing closing brace
* Refactor: Use %w for error wrapping and errors.As for extraction
* Fix: Disable retry logic inside transactions
There is a mistmatch in the conditionals for the definition and mounting of the `config-users` volume in the filer's template.
Volume definition:
```
{{- if and .Values.filer.s3.enabled .Values.filer.s3.enableAuth }}
```
Mount:
```
{{- if .Values.filer.s3.enableAuth }}
```
This leads to an invalid specification in the case where s3 is disabled but the enableAuth value is set to true, as it tries to mount in an undefined volume. I've fixed it here by adding the extra check to the latter conditional.
Fixes#7990
The issue was that the Charset constant used for generating secret keys
included the '/' character, which is URL-unsafe. When secret keys
containing '/' were used in HTTP requests, they would be URL-encoded,
causing a mismatch during signature verification.
Changes:
- Removed '/' from the Charset constant in weed/iam/constants.go
- Added TestGenerateSecretAccessKey_URLSafe to verify generated keys
don't contain URL-unsafe characters like '/' or '+'
This ensures all newly generated secret keys are URL-safe and will
work correctly with S3 authentication. Existing keys continue to work.
Previously, `weed mini` logic duplicated the credential loading process
by creating a temporary IAM config file from environment variables.
`auth_credentials.go` also had fallback logic to load these variables.
This change:
1. Updates `auth_credentials.go` to *always* check for and merge
AWS environment variable credentials (`AWS_ACCESS_KEY_ID`, etc.)
into the identity list. This ensures they are available regardless
of whether other configurations (static file or filer) are loaded.
2. Removes the redundant file creation logic from `weed/command/mini.go`.
3. Updates `weed mini` user messages to accurately reflect that
credentials are loaded from environment variables in-memory.
This results in a cleaner implementation where `weed/s3api` manages
all credential loading logic, and `weed mini` simply relies on it.
Refactored `NewIdentityAccessManagementWithStore` to remove mutual
exclusivity between static (file-based) and dynamic (filer-based)
configuration loading.
Previously, if a static config configuration was present (including the
legacy `IamConfig` option used by `weed mini`), it prevented loading
users from the filer.
Now, the system loads the static configuration first (if present), and
then *always* attempts to merge in the dynamic configuration from the
filer. This ensures that:
1. Static users (e.g. from `weed mini` env vars or `-s3.config`) are loaded and protected.
2. Dynamic users (e.g. created via Admin UI and stored in Filer) are also loaded and available.
`weed mini` sets the `-s3.iam.config` flag instead of `-s3.config`,
which populates `S3ApiServerOption.IamConfig`.
Previously, `NewIdentityAccessManagementWithStore` only checked
`option.Config`. This caused `weed mini` generated credentials (written
to a temp file passed via IamConfig) to be ignored, breaking S3 access
in mini mode even when environment variables were provided.
This change ensures we try to load the configuration from `IamConfig`
if `Config` is empty, restoring functionality for `weed mini`.
Fixed regression where AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
environment variables were not being loaded as fallback credentials.
The issue was that configLoaded was set to true when filer call
succeeded, even if it returned an empty configuration. This blocked
the environment variable fallback logic.
Now only set configLoaded = true when we actually have loaded
identities, allowing env vars to work correctly in mini mode and
other scenarios where filer config is empty.
* fix(s3api): ensure static config file takes precedence over dynamic updates
When a static S3 configuration file is provided, avoid overwriting
the configuration from dynamic filer updates. This ensures the
documented "Highest Priority" for the configuration file is respected.
* refactor(s3api): implement merge-based static config with immutable identities
Static identities from config file are now immutable and protected from
dynamic updates. Dynamic identities (from admin panel) can be added and
updated without affecting static entries.
- Track identity names loaded from static config file
- Implement merge logic that preserves static identities
- Allow dynamic identities to be added or updated
- Remove blanket block on config file updates
* fix: address PR review comments for static config merge logic
Critical Bugs:
- Fix existingIdx always-false condition causing duplicate identities
- Fix race condition in static config initialization (move useStaticConfig inside mutex)
Security & Robustness:
- Add nil identity check in VerifyActionPermission to fail closed
- Mask access keys in STS validation logs to avoid exposing credentials
- Add nil guard for s3a.iam in subscription handler
Test Improvements:
- Add authCalled tracking to MockIAMIntegration for explicit verification
- Lower log level for static config messages to reduce noise
* fix: prevent duplicates and race conditions in merge logic
Data Integrity:
- Prevent service account credential duplicates on repeated merges
- Clean up stale accessKeyIdent entries when replacing identities
- Check existing credentials before appending
Concurrency Safety:
- Add synchronization to IsStaticConfig method
Test Improvements:
- Add mux route vars for proper GetBucketAndObject extraction
- Add STS session token header to trigger correct auth path
* Fix STS authorization in streaming/chunked uploads
During streaming/chunked uploads (SigV4 streaming), authorization happens
twice:
1. Initial authorization in authRequestWithAuthType() - works correctly
2. Second authorization in verifyV4Signature() - was failing for STS
The issue was that verifyV4Signature() only used identity.canDo() for
permission checks, which always denies STS identities (they have empty
Actions). This bypassed IAM authorization completely.
This commit makes verifyV4Signature() IAM-aware by adding the same
fallback logic used in authRequestWithAuthType():
- Traditional identities (with Actions) use legacy canDo() check
- STS/JWT identities (empty Actions) fall back to IAM authorization
Fixes: https://github.com/seaweedfs/seaweedfs/pull/7986#issuecomment-3723196038
* Add comprehensive unit tests for STS authorization in streaming uploads
Created test suite to verify that verifyV4Signature properly handles STS
identities by falling back to IAM authorization when shouldCheckPermissions
is true.
Tests cover:
- STS identities with IAM integration (allow and deny cases)
- STS identities without IAM integration (should deny)
- Traditional identities with Actions (canDo check)
- Permission check bypass when shouldCheckPermissions=false
- Specific streaming upload scenario from bug report
- Action determination based on HTTP method
All tests pass successfully.
* Refactor authorization logic to avoid duplication
Centralized the authorization logic into IdentityAccessManagement.VerifyActionPermission.
Updated auth_signature_v4.go and auth_credentials.go to use this new helper.
Updated tests to clarify that they mirror the centralized logic.
* Refactor tests to use VerifyActionPermission directly
Introduced IAMIntegration interface to facilitate mocking of internal IAM integration logic.
Updated IdentityAccessManagement to use the interface.
Updated tests to directy call VerifyActionPermission using a mocked IAM integration, eliminating duplicated logic in tests.
* fix(s3api): ensure static config file takes precedence and refactor tests
- Track if configuration was loaded from a static file using `useStaticConfig`.
- Ignore filer-based IAM updates when a static configuration is in use to respect "Highest Priority" rule.
- Refactor `TestVerifyV4SignatureWithSTSIdentity` to use `VerifyActionPermission` directly.
- Fix typed nil interface panic in authorization test.
* Fix: Add delimiter support to ListObjectVersions with proper truncation
- Implemented delimiter support to group keys into CommonPrefixes
- Fixed critical truncation bug: now merges versions and common prefixes into single sorted list before truncation
- Ensures total items never exceed MaxKeys (prevents infinite pagination loops)
- Properly sets NextKeyMarker and NextVersionIdMarker for pagination
- Added integration tests in test/s3/versioning/s3_versioning_delimiter_test.go
- Verified behavior matches S3 API specification
* Fix: Add delimiter support to ListObjectVersions with proper truncation
- Implemented delimiter support to group keys into CommonPrefixes
- Fixed critical truncation bug: now merges versions and common prefixes before truncation
- Added safety guard for maxKeys=0 to prevent panics
- Condensed verbose comments for better readability
- Added robust Go integration tests with nil checks for AWS SDK pointers
- Verified behavior matches S3 API specification
- Resolved compilation error in integration tests
- Refined pagination comments and ensured exclusive KeyMarker behavior
- Refactored listObjectVersions into helper methods for better maintainability