filer: require admin-signed JWT on the IAM gRPC service (#9442)

Every IAM RPC (CreateUser, PutPolicy, CreateAccessKey, ...) now requires
a Bearer token in the authorization metadata, signed with the filer
write-signing key. The service refuses to register on a filer that has
no jwt.filer_signing.key set, so the unauthenticated default is gone:
operators who use these RPCs must configure the key and attach a token
on every call.

Bearer scheme matching is case-insensitive (RFC 6750), every handler
nil-checks req before dereferencing it, and tests now cover the
expired-token path.
This commit is contained in:
Chris Lu
2026-05-12 10:11:08 -07:00
committed by GitHub
parent 05ed5c9ae8
commit 5e8f99f40a
5 changed files with 344 additions and 7 deletions
+15 -4
View File
@@ -431,11 +431,22 @@ func (fo *FilerOptions) startFiler() {
grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.filer"))
filer_pb.RegisterSeaweedFilerServer(grpcS, fs)
// Register IAM gRPC service if credential manager is available
// Register IAM gRPC service only when both a credential manager and an
// admin signing key are configured. The IAM RPCs can create users and
// mint access keys; mounting them on an unauthenticated listener would
// hand any caller that can reach the gRPC port S3-admin equivalent power.
// Operators who relied on the unauthenticated path must now set
// jwt.filer_signing.key in security.toml and attach a Bearer token signed
// with that key on every IAM call.
if credentialManager != nil {
iamGrpcServer := weed_server.NewIamGrpcServer(credentialManager)
iam_pb.RegisterSeaweedIdentityAccessManagementServer(grpcS, iamGrpcServer)
glog.V(0).Info("Registered IAM gRPC service on filer")
adminSigningKey := security.SigningKey(util.GetViper().GetString("jwt.filer_signing.key"))
if len(adminSigningKey) == 0 {
glog.Warningf("IAM gRPC service NOT registered on filer: jwt.filer_signing.key is empty in security.toml; configure it to enable IAM administration")
} else {
iamGrpcServer := weed_server.NewIamGrpcServer(credentialManager, adminSigningKey)
iam_pb.RegisterSeaweedIdentityAccessManagementServer(grpcS, iamGrpcServer)
glog.V(0).Info("Registered IAM gRPC service on filer (admin Bearer token required)")
}
}
reflection.Register(grpcS)
+5
View File
@@ -44,6 +44,11 @@ expires_after_seconds = 10 # seconds
# - f.e. the S3 API Shim generates the JWT
# - the Filer server validates the JWT on writing
# NOTE: This key is ALSO used as a fallback signing key for S3 STS if s3.iam.config does not specify a signingKey.
# NOTE: This key is ALSO required to mount the IAM gRPC service (CreateUser,
# PutPolicy, CreateAccessKey, ...) on the filer. The filer refuses to
# register that service when the key is empty, and every IAM RPC must
# carry a Bearer token signed with this key in its "authorization"
# gRPC metadata. Mint such a token with security.GenJwtForFilerAdmin.
# the jwt defaults to expire after 10 seconds.
[jwt.filer_signing]
key = ""