LiveKit.AccessToken (LiveKit v0.1.0)

Copy Markdown View Source

Builds and signs LiveKit access tokens.

Tokens are built with an immutable, pipeline-friendly API and signed with HS256 using the API secret:

iex> {:ok, jwt} =
...>   LiveKit.AccessToken.new(
...>     api_key: "api-key",
...>     api_secret: "api-secret",
...>     identity: "user-123"
...>   )
...>   |> LiveKit.AccessToken.with_name("Alice")
...>   |> LiveKit.AccessToken.with_metadata(~s({"role":"host"}))
...>   |> LiveKit.AccessToken.with_video_grant(%LiveKit.Grants.Video{
...>     room_join: true,
...>     room: "support-room"
...>   })
...>   |> LiveKit.AccessToken.to_jwt()
iex> is_binary(jwt)
true

Claims

The signed payload contains the registered claims iss (the API key), sub (the identity, when set), iat, nbf and exp, alongside the LiveKit claims produced by LiveKit.Grants.to_claims/1. The API secret is only ever used as the signing key and never appears in the payload.

Time

The default TTL is 21600 seconds (6 hours), matching the Go and JavaScript SDKs. TTLs must be positive. Time is read through an injectable clock so tests can be deterministic:

LiveKit.AccessToken.new(
  api_key: "k",
  api_secret: "s",
  clock: fn -> 1_700_000_000 end
)

Summary

Functions

The default token lifetime in seconds.

Starts building a token.

Builds the full claim map that would be signed, including registered claims.

Signs the token and returns the encoded JWT.

Same as to_jwt/1 but raises LiveKit.Error on failure.

Sets the agent grant.

Sets the participant attributes.

Sets the participant identity, encoded as the sub claim.

Sets the participant metadata string.

Sets the participant display name.

Sets the sha256 claim used by LiveKit webhook tokens.

Sets the sip grant.

Sets the token lifetime in seconds.

Sets the video grant.

Types

clock()

@type clock() :: (-> integer())

t()

@type t() :: %LiveKit.AccessToken{
  api_key: String.t() | nil,
  api_secret: String.t() | nil,
  claims: LiveKit.Grants.Claims.t(),
  clock: clock(),
  identity: String.t() | nil,
  ttl: integer()
}

Functions

default_ttl()

@spec default_ttl() :: pos_integer()

The default token lifetime in seconds.

Examples

iex> LiveKit.AccessToken.default_ttl()
21_600

new(opts \\ [])

@spec new(keyword()) :: t()

Starts building a token.

Options

  • :api_key - LiveKit API key, used as the iss claim.
  • :api_secret - LiveKit API secret, used as the HS256 signing key.
  • :identity - participant identity, encoded as sub.
  • :name - participant display name.
  • :metadata - participant metadata string.
  • :attributes - map of string key/value participant attributes.
  • :ttl - lifetime in seconds. Defaults to 21_600.
  • :clock - zero-arity function returning the current Unix time in seconds. Defaults to System.system_time(:second).

Credentials are validated when the token is signed, not here, so building is never fallible.

Examples

iex> token = LiveKit.AccessToken.new(api_key: "k", api_secret: "s", identity: "u1")
iex> {token.identity, token.ttl}
{"u1", 21_600}

to_claims(token)

@spec to_claims(t()) :: {:ok, map()} | {:error, LiveKit.Error.t()}

Builds the full claim map that would be signed, including registered claims.

Examples

iex> {:ok, claims} =
...>   LiveKit.AccessToken.new(api_key: "k", api_secret: "s", identity: "u1", clock: fn -> 1_700_000_000 end)
...>   |> LiveKit.AccessToken.with_video_grant(%LiveKit.Grants.Video{room_list: true})
...>   |> LiveKit.AccessToken.to_claims()
iex> {claims["iss"], claims["sub"], claims["exp"] - claims["iat"]}
{"k", "u1", 21_600}

to_jwt(token)

@spec to_jwt(t()) :: {:ok, String.t()} | {:error, LiveKit.Error.t()}

Signs the token and returns the encoded JWT.

Examples

iex> {:ok, jwt} =
...>   LiveKit.AccessToken.new(api_key: "k", api_secret: "s")
...>   |> LiveKit.AccessToken.with_video_grant(%LiveKit.Grants.Video{room_list: true})
...>   |> LiveKit.AccessToken.to_jwt()
iex> length(String.split(jwt, "."))
3

iex> {:error, error} = LiveKit.AccessToken.new(api_key: "k", api_secret: "s") |> LiveKit.AccessToken.with_ttl(0) |> LiveKit.AccessToken.to_jwt()
iex> error.type
:validation

to_jwt!(token)

@spec to_jwt!(t()) :: String.t()

Same as to_jwt/1 but raises LiveKit.Error on failure.

Examples

iex> jwt =
...>   LiveKit.AccessToken.new(api_key: "k", api_secret: "s")
...>   |> LiveKit.AccessToken.with_video_grant(%LiveKit.Grants.Video{room_list: true})
...>   |> LiveKit.AccessToken.to_jwt!()
iex> is_binary(jwt)
true

with_agent_grant(token, grant)

@spec with_agent_grant(t(), LiveKit.Grants.Agent.t()) :: t()

Sets the agent grant.

Examples

iex> token = LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_agent_grant(%LiveKit.Grants.Agent{admin: true})
iex> token.claims.agent.admin
true

with_attributes(token, attributes)

@spec with_attributes(t(), %{required(String.t()) => String.t()}) :: t()

Sets the participant attributes.

Examples

iex> token = LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_attributes(%{"tier" => "pro"})
iex> token.claims.attributes
%{"tier" => "pro"}

with_identity(token, identity)

@spec with_identity(t(), String.t()) :: t()

Sets the participant identity, encoded as the sub claim.

Examples

iex> LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_identity("user-1") |> Map.fetch!(:identity)
"user-1"

with_metadata(token, metadata)

@spec with_metadata(t(), String.t()) :: t()

Sets the participant metadata string.

Examples

iex> token = LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_metadata(~s({"role":"host"}))
iex> token.claims.metadata
~s({"role":"host"})

with_name(token, name)

@spec with_name(t(), String.t()) :: t()

Sets the participant display name.

Examples

iex> token = LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_name("Alice")
iex> token.claims.name
"Alice"

with_sha256(token, sha256)

@spec with_sha256(t(), String.t()) :: t()

Sets the sha256 claim used by LiveKit webhook tokens.

The value is the Base64-encoded SHA-256 digest of the raw webhook body.

Examples

iex> token = LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_sha256("abc=")
iex> token.claims.sha256
"abc="

with_sip_grant(token, grant)

@spec with_sip_grant(t(), LiveKit.Grants.SIP.t()) :: t()

Sets the sip grant.

Examples

iex> token = LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_sip_grant(%LiveKit.Grants.SIP{admin: true})
iex> token.claims.sip.admin
true

with_ttl(token, ttl)

@spec with_ttl(t(), integer()) :: t()

Sets the token lifetime in seconds.

Invalid values are kept as-is and reported by to_jwt/1, so pipelines stay free of tuple handling.

Examples

iex> LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_ttl(60) |> Map.fetch!(:ttl)
60

with_video_grant(token, grant)

@spec with_video_grant(t(), LiveKit.Grants.Video.t()) :: t()

Sets the video grant.

Examples

iex> token = LiveKit.AccessToken.new() |> LiveKit.AccessToken.with_video_grant(%LiveKit.Grants.Video{room_list: true})
iex> token.claims.video.room_list
true