Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
26a4490
Basic providers with cache
pblazej Sep 16, 2025
b0cf3a7
Split token server
pblazej Sep 16, 2025
d88c2fb
Pass options
pblazej Sep 16, 2025
5aacd73
Expose RoomConfiguration (without pb)
pblazej Sep 16, 2025
b7e999e
Add some tests
pblazej Sep 16, 2025
e311976
Cmts
pblazej Sep 16, 2025
894d24e
Extract storage
pblazej Sep 16, 2025
d2c10ea
Change
pblazej Sep 16, 2025
f20c249
Expose cached, naming
pblazej Sep 17, 2025
44a4b8e
JSON keys
pblazej Sep 17, 2025
69d2ce0
Cache provider
pblazej Sep 17, 2025
1d12469
Log
pblazej Sep 17, 2025
8109684
Renaming
pblazej Sep 19, 2025
6b2eb9c
Fix tests
pblazej Sep 19, 2025
96c4ba5
Move Sandbox
pblazej Sep 19, 2025
43df84e
Public, comments
pblazej Sep 19, 2025
18ea71b
Nitpicks
pblazej Sep 19, 2025
cdd5f1c
Change
pblazej Sep 19, 2025
3d45795
JWT
pblazej Sep 19, 2025
aa2f08c
Filter
pblazej Sep 19, 2025
8673296
Keys
pblazej Sep 24, 2025
748ddd6
Mutable variant with setRequest
pblazej Sep 24, 2025
0c89008
Revert "Mutable variant with setRequest"
pblazej Sep 25, 2025
22f8d77
Remove Room integration
pblazej Oct 2, 2025
eea7c26
WIP
pblazej Oct 2, 2025
b57e454
Move, fix serialization
pblazej Oct 3, 2025
71fe3dd
Fix tests
pblazej Oct 3, 2025
4bbdca8
Move
pblazej Oct 3, 2025
6ce5ad8
Comments
pblazej Oct 3, 2025
6a4474a
Fix tests
pblazej Oct 3, 2025
86a445b
Merge branch 'main' into blaze/connection-provider
pblazej Oct 7, 2025
6feec3e
Move tests
pblazej Oct 7, 2025
69ee5ed
Extract options
pblazej Oct 14, 2025
b71debc
Merge branch 'main' into blaze/connection-provider
pblazej Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changes/connection-credentials
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
patch type="added" "Abstract token source for easier token fetching in production and faster integration with sandbox environment"
6 changes: 2 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ let package = Package(
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.31.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"),
.package(url: "https://github.com/apple/swift-collections.git", "1.1.0" ..< "1.3.0"),
.package(url: "https://github.com/vapor/jwt-kit.git", from: "4.13.5"),
// Only used for DocC generation
.package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.3.0"),
// Only used for Testing
.package(url: "https://github.com/vapor/jwt-kit.git", from: "4.13.4"),
],
targets: [
.target(
Expand All @@ -41,6 +40,7 @@ let package = Package(
.product(name: "DequeModule", package: "swift-collections"),
.product(name: "OrderedCollections", package: "swift-collections"),
.product(name: "Logging", package: "swift-log"),
.product(name: "JWTKit", package: "jwt-kit"),
"LKObjCHelpers",
],
exclude: [
Expand All @@ -57,14 +57,12 @@ let package = Package(
name: "LiveKitTests",
dependencies: [
"LiveKit",
.product(name: "JWTKit", package: "jwt-kit"),
]
),
.testTarget(
name: "LiveKitTestsObjC",
dependencies: [
"LiveKit",
.product(name: "JWTKit", package: "jwt-kit"),
]
),
],
Expand Down
6 changes: 2 additions & 4 deletions Package@swift-6.0.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ let package = Package(
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.31.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"),
.package(url: "https://github.com/apple/swift-collections.git", "1.1.0" ..< "1.3.0"),
.package(url: "https://github.com/vapor/jwt-kit.git", from: "4.13.5"),
// Only used for DocC generation
.package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.3.0"),
// Only used for Testing
.package(url: "https://github.com/vapor/jwt-kit.git", from: "4.13.4"),
],
targets: [
.target(
Expand All @@ -42,6 +41,7 @@ let package = Package(
.product(name: "DequeModule", package: "swift-collections"),
.product(name: "OrderedCollections", package: "swift-collections"),
.product(name: "Logging", package: "swift-log"),
.product(name: "JWTKit", package: "jwt-kit"),
"LKObjCHelpers",
],
exclude: [
Expand All @@ -58,14 +58,12 @@ let package = Package(
name: "LiveKitTests",
dependencies: [
"LiveKit",
.product(name: "JWTKit", package: "jwt-kit"),
]
),
.testTarget(
name: "LiveKitTestsObjC",
dependencies: [
"LiveKit",
.product(name: "JWTKit", package: "jwt-kit"),
]
),
],
Expand Down
99 changes: 99 additions & 0 deletions Sources/LiveKit/Auth/JWT.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2025 LiveKit
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import JWTKit

public struct LiveKitJWTPayload: JWTPayload, Codable, Equatable {
public struct VideoGrant: Codable, Equatable {
/// Name of the room, must be set for admin or join permissions
public let room: String?
/// Permission to create a room
public let roomCreate: Bool?
/// Permission to join a room as a participant, room must be set
public let roomJoin: Bool?
/// Permission to list rooms
public let roomList: Bool?
/// Permission to start a recording
public let roomRecord: Bool?
/// Permission to control a specific room, room must be set
public let roomAdmin: Bool?

/// Allow participant to publish. If neither canPublish or canSubscribe is set, both publish and subscribe are enabled
public let canPublish: Bool?
/// Allow participant to subscribe to other tracks
public let canSubscribe: Bool?
/// Allow participants to publish data, defaults to true if not set
public let canPublishData: Bool?
/// Allowed sources for publishing
public let canPublishSources: [String]?
/// Participant isn't visible to others
public let hidden: Bool?
/// Participant is recording the room, when set, allows room to indicate it's being recorded
public let recorder: Bool?

public init(room: String? = nil,
roomCreate: Bool? = nil,
roomJoin: Bool? = nil,
roomList: Bool? = nil,
roomRecord: Bool? = nil,
roomAdmin: Bool? = nil,
canPublish: Bool? = nil,
canSubscribe: Bool? = nil,
canPublishData: Bool? = nil,
canPublishSources: [String]? = nil,
hidden: Bool? = nil,
recorder: Bool? = nil)
{
self.room = room
self.roomCreate = roomCreate
self.roomJoin = roomJoin
self.roomList = roomList
self.roomRecord = roomRecord
self.roomAdmin = roomAdmin
self.canPublish = canPublish
self.canSubscribe = canSubscribe
self.canPublishData = canPublishData
self.canPublishSources = canPublishSources
self.hidden = hidden
self.recorder = recorder
}
}

/// Expiration time claim
public let exp: ExpirationClaim
/// Issuer claim
public let iss: IssuerClaim
/// Not before claim
public let nbf: NotBeforeClaim
/// Subject claim
public let sub: SubjectClaim

/// Participant name
public let name: String?
/// Participant metadata
public let metadata: String?
/// Video grants for the participant
public let video: VideoGrant?

public func verify(using _: JWTSigner) throws {
try nbf.verifyNotBefore()
try exp.verifyNotExpired()
}

static func fromUnverified(token: String) -> Self? {
try? JWTSigners().unverified(token, as: Self.self)
}
}
35 changes: 35 additions & 0 deletions Sources/LiveKit/Auth/Sandbox.swift
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved it to a separate file for visibility.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2025 LiveKit
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Foundation

/// `Sandbox` queries LiveKit Sandbox token server for credentials,
/// which supports quick prototyping/getting started types of use cases.
/// - Warning: This token endpoint is **INSECURE** and should **NOT** be used in production.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public struct Sandbox: TokenEndpoint {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, is this like mostly for prototyping ?

I am wondering if we should name it as LiveKitSandbox ? so that it will be more explicit. And we can use similar approaches for other prototype APIs.

public let url = URL(string: "https://cloud-api.livekit.io/api/sandbox/connection-details")!
public var headers: [String: String] {
["X-Sandbox-ID": id]
}

/// The sandbox ID provided by LiveKit Cloud.
public let id: String

/// Initialize with a sandbox ID from LiveKit Cloud.
public init(id: String) {
self.id = id.trimmingCharacters(in: .alphanumerics.inverted)
}
}
Loading
Loading