fix(service): keep the observability grant on refreshed tokens

refreshToken copied grants field by field and dropped observability, so a
client that adopted the first refresh (sent at join) lost the grant within
a second, and one that kept its join token lost it at expiry. Keep the join
token's grant on every refresh; never add one.
This commit is contained in:
Błażej Pankowski committed 2026-10-22 11:05:36 +02:00
1 parent a390d03d28
commit 0105e92a4f
2 files changed
+46 -1

No files matched your search

+3 -1
View File
@@ -1178,7 +1178,9 @@ func (r *RoomManager) refreshToken(participant types.LocalParticipant) error {
SetAttributes(grants.Attributes).
SetVideoGrant(grants.Video).
SetRoomConfig(grants.GetRoomConfiguration()).
SetRoomPreset(grants.RoomPreset)
SetRoomPreset(grants.RoomPreset).
// keep the join token's grant; self-hosted never adds one, as there is no Cloud ingest behind it
SetObservabilityGrant(grants.Observability)
jwt, err := token.ToJWT()
if err == nil {
err = participant.SendRefreshToken(jwt)
+43
View File
@@ -0,0 +1,43 @@
package service
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/livekit/protocol/auth"
"github.com/livekit/protocol/utils"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/rtc/types/typesfakes"
)
// refreshToken backs every refresh: the first one at join, the periodic tick and claims changes.
func TestRefreshTokenKeepsObservabilityGrant(t *testing.T) {
for name, obs := range map[string]*auth.ObservabilityGrant{
"none": nil,
"write": {Write: true},
} {
t.Run(name, func(t *testing.T) {
secret := utils.RandomSecret()
r := &RoomManager{config: &config.Config{Keys: map[string]string{"APIkey": secret}}}
p := &typesfakes.FakeLocalParticipant{}
p.IdentityReturns("alice")
p.ClaimGrantsReturns(&auth.ClaimGrants{
Identity: "alice",
Video: &auth.VideoGrant{RoomJoin: true, Room: "room"},
Observability: obs,
})
require.NoError(t, r.refreshToken(p))
require.Equal(t, 1, p.SendRefreshTokenCallCount())
v, err := auth.ParseAPIToken(p.SendRefreshTokenArgsForCall(0))
require.NoError(t, err)
_, grants, err := v.Verify(secret)
require.NoError(t, err)
require.Equal(t, obs, grants.Observability, "kept as joined, never added")
})
}
}