livekit-token: the agent grant, the kind claim, and no default claims - #1419
Open
theomonnom wants to merge 2 commits into
Open
livekit-token: the agent grant, the kind claim, and no default claims#1419theomonnom wants to merge 2 commits into
theomonnom wants to merge 2 commits into
Conversation
Contributor
Changeset ✓This PR includes a changeset covering all affected packages:
|
theomonnom
force-pushed
the
theo/token-agent-kind
branch
2 times, most recently
from
September 9, 2026 19:44
74d675c to
90527d4
Compare
theomonnom
force-pushed
the
theo/token-agent-kind
branch
2 times, most recently
from
September 9, 2026 19:48
5e0f9d8 to
1a5147a
Compare
theomonnom
force-pushed
the
theo/token-agent-kind
branch
2 times, most recently
from
September 9, 2026 19:55
08186b6 to
8f812bd
Compare
ladvoc
requested changes
Sep 9, 2026
Contributor
There was a problem hiding this comment.
Generally looks good, a few points to address:
- Since we expose token generation/verification through
livekit-uniffinow, you'll need to update there to use the new API. - Changeset should specify major as the release type (this is necessary because it is a pre-1.0 release; the actual bump will be semver minor)
- Changeset also needs to list all crates that depend on this crate (release manager is not dependency aware right now unfortunately)
`VideoGrants` gains `agent` and `Claims` gains `kind` (with `AccessToken::with_kind`),
both of which the Go, Python and JS SDKs already carry. An agent worker authenticates
to `/agent` with `VideoGrants { agent: true }` and a simulated job's participant token
is `kind: "agent"`; neither could be minted from Rust before, so livekit/agents-rust
was about to hand-roll the claims over jsonwebtoken instead of using this crate.
The four grants the server infers when absent -- canPublish, canSubscribe,
canPublishData, canUpdateOwnMetadata (protocol/auth/grants.go) -- become `Option<bool>`,
as in the Go and JS SDKs: `None` leaves the decision to the server, and getters read a
token the way the server does, `canPublishData` falling back to `canPublish` included.
With that, `VideoGrants` derives `Default` and nothing at its default is written into the
token: every claim and grant carries `skip_serializing_if = "is_default"`, the one
predicate, and the token holds only what was set -- as the server's own `omitempty`
grants are. Verification of existing tokens is unchanged; a round-trip test pins that
`{}` and the defaults are the same thing.
`livekit-uniffi` follows: its `VideoGrants` record mirrors the struct field for field,
and `kind` is exposed on `TokenOptions` and `Claims`.
theomonnom
force-pushed
the
theo/token-agent-kind
branch
from
September 9, 2026 20:01
8f812bd to
ebd80e5
Compare
The livekit integration tests and the data_track_benchmark and local_video examples still set canPublish / canSubscribe / canPublishData as plain bools; they are Some(..) now. Cargo.lock picks up the serde_json dev-dependency and the two new unit tests are rustfmt'd.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
VideoGrantsgains theagentgrant andClaimsgains thekindclaim, withAccessToken::with_kind. The Go, Python and JS SDKs already carry both.livekit-uniffiexposes them too:TokenOptions.kind,Claims.kind, andagenton itsVideoGrantsrecord.Why: an agent worker authenticates to
/agentwithVideoGrants(agent=True), and a simulated job's participant token iskind: "agent". Neither could be minted from Rust, so livekit/agents-rust was about to hand-roll these claims over jsonwebtoken instead of depending on this crate.The inferred grants become
Option<bool>(breaking). The server infers four grants when absent (protocol/auth/grants.go):canPublishandcanSubscribe→ true,canUpdateOwnMetadata→ false, andcanPublishData→ whatevercanPublishis. The Go and JS SDKs model these as optional; this crate had them asboolwith adefault_trueon the read side, which cannot say "unset" and read an absentcanPublishDataastruerather than ascanPublish. NowNoneleaves the decision to the server and the getters (can_publish(),can_subscribe(),can_publish_data(),can_update_own_metadata()) read a token the way the server does. Every other default checked against the server's getters matches. No crate in this workspace sets or reads those four fields directly.No default claims. With the four as
Option,VideoGrantsderivesDefault, and nothing at its default is written into the token: every claim and grant carriesskip_serializing_if = "is_default", one predicate, no hand-writtenSerialize. Unset claims (sub,name,kind,metadata,sha256,attributes,roomConfig) and grants at their default (video,sip, and every field in them) are omitted, as the server's ownomitemptygrants are. Verification of existing tokens is unchanged.Changeset:
majorforlivekit-token(pre-1.0, so the actual bump is semver-minor),livekit-uniffi(its record shape changed) andlivekit-api(it re-exports the crate aslivekit_api::access_token, so^0.1.2would otherwise miss the release);patchfor the internal userslivekit,livekit-ffi,livekit-signaling.Tests: the two new claims round-trip through
to_jwt/verify; a token with nothing set carries exactlyexp,iss,nbf;{}andVideoGrants::default()/SIPGrants::default()/a bareClaimsare the same thing in both directions; an absentcanPublishDatareads ascanPublish.livekit-uniffi,livekit-apiandlivekit-token-sourcecompile.🤖 Generated with Claude Code