filer: say jwt.filer_signing.key gates only the IAM gRPC service (#12353)

* filer: say jwt.filer_signing.key gates only the IAM gRPC service

The key never covered the rest of the filer gRPC port, which can read and
write the IAM store under /etc/iam. Point operators at [grpc.filer] mTLS for a
port reachable beyond a trusted network instead of the key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* filer: note the IAM gRPC OIDC provider and role RPCs are refused without the key

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chris LuandClaude Opus 5.5 authored and GitHub committed 2026-11-02 18:00:59 -08:00
1 parent cc71cc9585
commit c2ca83c0bf
3 files changed
+13 -14

No files matched your search

+3 -6
View File
@@ -506,12 +506,9 @@ func (fo *FilerOptions) startFiler() {
grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.filer"))
filer_pb.RegisterSeaweedFilerServer(grpcS, fs)
// Register the IAM gRPC service. Auth is opt-in: when
// jwt.filer_signing.key is configured the service requires a Bearer token
// signed with that key; otherwise it runs unauthenticated, matching the
// rest of the filer's gRPC surface. Operators who expose the filer gRPC
// port beyond a trusted network should set jwt.filer_signing.key on both
// the filer and the admin server.
// IAM RPCs require a Bearer token signed with jwt.filer_signing.key when it
// is set. The key does not protect the rest of this port; that needs
// [grpc.filer] mTLS.
if credentialManager != nil {
adminSigningKey := security.SigningKey(util.GetViper().GetString("jwt.filer_signing.key"))
iamGrpcServer := weed_server.NewIamGrpcServer(credentialManager, adminSigningKey)
+5 -3
View File
@@ -57,9 +57,11 @@ expires_after_seconds = 10 # seconds
# CreateAccessKey, ...). When set, every IAM RPC must carry a Bearer
# token signed with this key in its "authorization" gRPC metadata; mint
# such a token with security.GenJwtForFilerAdmin. When empty, the IAM
# gRPC service runs unauthenticated, like the rest of the filer's gRPC
# surface — set the key on both filer and admin if the gRPC port is
# reachable beyond a trusted network.
# gRPC service runs unauthenticated and refuses its OIDC provider and
# role RPCs. When set, set it on both filer and admin.
# The key does not protect the other filer gRPC RPCs, which can read and
# write the IAM store under /etc/iam; if the filer gRPC port is reachable
# beyond a trusted network, enable [grpc.filer] mTLS below.
# the jwt defaults to expire after 10 seconds.
[jwt.filer_signing]
key = ""
@@ -17,11 +17,11 @@ import (
)
// IamGrpcServer implements the IAM gRPC service on the filer.
// Auth is opt-in: when jwt.filer_signing.key is set in security.toml the
// service requires a Bearer token in the "authorization" metadata signed with
// that key; when it is empty every RPC is accepted unauthenticated, matching
// the rest of SeaweedFS's gRPC surface. Operators who expose the filer gRPC
// port beyond a trusted network should configure the key.
// When jwt.filer_signing.key is set, every RPC requires a Bearer token signed
// with it; otherwise RPCs run unauthenticated, except the OIDC provider and
// role RPCs, which are refused. The key gates only this service: the filer RPCs
// on the same port can still read and write the IAM store under /etc/iam.
// Protect a filer gRPC port reachable by untrusted clients with [grpc.filer] mTLS.
type IamGrpcServer struct {
iam_pb.UnimplementedSeaweedIdentityAccessManagementServer
credentialManager *credential.CredentialManager