* admin: attach admin-signed Bearer token on filer IAM gRPC calls PR #9442 added Bearer-JWT enforcement on the filer's IAM gRPC service but didn't update its only production client, IamGrpcStore. The admin UI Users/Groups pages went through that client and started failing in 4.24 with either Unimplemented (filer refuses to register the service when jwt.filer_signing.key is empty) or Unauthenticated (the client sent no token). Issues #9495 and #9496 both trace to this gap. Plumb jwt.filer_signing.key into IamGrpcStore via a new SetAdminSigning hook called from the admin server, and append a freshly minted Bearer token to outgoing metadata on every call. The mint helper security.GenJwtForFilerAdmin existed since #9442 but had no production caller; this wires it up. Add an integration test alongside grpc_store.go that runs a real IamGrpcServer over a real grpc.Server listener and exercises the store end-to-end: matching key succeeds, wrong key returns Unauthenticated, no key returns Unauthenticated. Without the client-side token attach the success path fails, so the regression cannot land again. * address review: include adminSigningExpiresAfterSec in mu comment
Credential Store Integration
This document shows how the credential store has been integrated into SeaweedFS's S3 API and IAM API components.
Quick Start
-
Generate credential configuration:
weed scaffold -config=credential -output=. -
Edit credential.toml to enable your preferred store (filer_etc is enabled by default)
-
Start S3 API server - it will automatically load credential.toml:
weed s3 -filer=localhost:8888
Integration Overview
The credential store provides a pluggable backend for storing S3 identities and credentials, supporting:
- Filer-based storage (filer_etc) - Uses existing filer storage (default)
- PostgreSQL - Shared database for multiple servers
- Memory - In-memory storage for testing
Configuration
Using credential.toml
Generate the configuration template:
weed scaffold -config=credential
This creates a credential.toml file with all available options. The filer_etc store is enabled by default:
# Filer-based credential store (default, uses existing filer storage)
[credential.filer_etc]
enabled = true
# PostgreSQL credential store (recommended for multi-node deployments)
[credential.postgres]
enabled = false
hostname = "localhost"
port = 5432
username = "seaweedfs"
password = "your_password"
database = "seaweedfs"
# Memory credential store (for testing only, data is lost on restart)
[credential.memory]
enabled = false
The credential.toml file is automatically loaded from these locations (in priority order):
./credential.toml$HOME/.seaweedfs/credential.toml/etc/seaweedfs/credential.toml
Server Configuration
Both S3 API and IAM API servers automatically load credential.toml during startup. No additional configuration is required.
Usage Examples
Filer-based Store (Default)
[credential.filer_etc]
enabled = true
This uses the existing filer storage and is compatible with current deployments.
PostgreSQL Store
[credential.postgres]
enabled = true
hostname = "localhost"
port = 5432
username = "seaweedfs"
password = "your_password"
database = "seaweedfs"
schema = "public"
sslmode = "disable"
table_prefix = "sw_"
connection_max_idle = 10
connection_max_open = 100
connection_max_lifetime_seconds = 3600
Memory Store (Testing)
[credential.memory]
enabled = true
Environment Variables
All credential configuration can be overridden with environment variables:
# Override PostgreSQL password
export WEED_CREDENTIAL_POSTGRES_PASSWORD=secret
# Override PostgreSQL hostname
export WEED_CREDENTIAL_POSTGRES_HOSTNAME=db.example.com
# Enable/disable stores
export WEED_CREDENTIAL_FILER_ETC_ENABLED=true
Rules:
- Prefix with
WEED_CREDENTIAL_ - Convert to uppercase
- Replace
.with_
Implementation Details
Components automatically load credential configuration during startup:
// Server initialization
if credConfig, err := credential.LoadCredentialConfiguration(); err == nil && credConfig != nil {
credentialManager, err := credential.NewCredentialManager(
credConfig.Store,
credConfig.Config,
credConfig.Prefix,
)
if err != nil {
return nil, fmt.Errorf("failed to initialize credential manager: %v", err)
}
// Use credential manager for operations
}
Benefits
- Easy Configuration - Generate template with
weed scaffold -config=credential - Pluggable Storage - Switch between filer_etc, PostgreSQL without code changes
- Backward Compatibility - Filer-based storage works with existing deployments
- Scalability - Database stores support multiple concurrent servers
- Performance - Database access can be faster than file-based storage
- Testing - Memory store simplifies unit testing
- Environment Override - All settings can be overridden with environment variables
Error Handling
When a credential store is configured, it must initialize successfully or the server will fail to start:
if credConfig != nil {
credentialManager, err = credential.NewCredentialManager(...)
if err != nil {
return nil, fmt.Errorf("failed to initialize credential manager: %v", err)
}
}
This ensures explicit configuration - if you configure a credential store, it must work properly.