Skip to content

Commit

Permalink
Deprecate ZTA-related fields (#2851)
Browse files Browse the repository at this point in the history
  • Loading branch information
aleDsz authored Nov 8, 2024
1 parent 6021ddf commit 473830a
Show file tree
Hide file tree
Showing 42 changed files with 135 additions and 243 deletions.
77 changes: 10 additions & 67 deletions lib/livebook/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,6 @@ defmodule Livebook.Config do
| %{mode: :token, secret: String.t()}
| %{mode: :disabled}

# Those are the public identity providers.
#
# There are still a :session and :custom identity providers,
# but those are handled internally.
#
# IMPORTANT: this list must be in sync with Livebook Teams.
@identity_providers [
%{
type: :basic_auth,
name: "Basic Auth",
value: "Credentials (username:password)",
module: Livebook.ZTA.BasicAuth,
placeholder: "username:password",
input: "password"
},
%{
type: :cloudflare,
name: "Cloudflare",
value: "Team name (domain)",
module: Livebook.ZTA.Cloudflare
},
%{
type: :google_iap,
name: "Google IAP",
value: "Audience (aud)",
module: Livebook.ZTA.GoogleIAP
},
%{
type: :livebook_teams,
name: "Livebook Teams",
module: Livebook.ZTA.LivebookTeams
},
%{
type: :tailscale,
name: "Tailscale",
value: "Tailscale CLI socket path",
module: Livebook.ZTA.Tailscale
}
]

@identity_provider_no_id [Livebook.ZTA.BasicAuth, Livebook.ZTA.PassThrough]

@identity_provider_type_to_module Map.new(@identity_providers, fn provider ->
{Atom.to_string(provider.type), provider.module}
end)

@doc """
Returns docker images to be used when generating sample Dockerfiles.
"""
Expand Down Expand Up @@ -282,16 +236,6 @@ defmodule Livebook.Config do
Application.fetch_env!(:livebook, :shutdown_callback)
end

@doc """
Returns all identity providers.
Internal identity providers, such as session and custom,
are not included.
"""
def identity_providers do
@identity_providers
end

@doc """
Returns the identity provider.
"""
Expand All @@ -303,6 +247,8 @@ defmodule Livebook.Config do
end
end

@identity_provider_no_id [Livebook.ZTA.BasicAuth, Livebook.ZTA.PassThrough]

@doc """
Returns if the identity data is readonly.
"""
Expand All @@ -312,14 +258,6 @@ defmodule Livebook.Config do
module not in @identity_provider_no_id
end

@doc """
Returns metadata of a ZTA provider
"""
@spec zta_metadata(atom()) :: map()
def zta_metadata(zta_provider) do
Enum.find(Livebook.Config.identity_providers(), &(&1.type == zta_provider))
end

@doc """
Returns whether the application is running inside an iframe.
"""
Expand Down Expand Up @@ -750,6 +688,13 @@ defmodule Livebook.Config do
end
end

@identity_providers %{
"basic_auth" => Livebook.ZTA.BasicAuth,
"cloudflare" => Livebook.ZTA.Cloudflare,
"google_iap" => Livebook.ZTA.GoogleIAP,
"tailscale" => Livebook.ZTA.Tailscale
}

@doc """
Parses zero trust identity provider from env.
"""
Expand All @@ -770,13 +715,11 @@ defmodule Livebook.Config do

provider ->
with [type, key] <- String.split(provider, ":", parts: 2),
%{^type => module} <- identity_provider_type_to_module() do
%{^type => module} <- @identity_providers do
{:zta, module, key}
else
_ -> abort!("invalid configuration for identity provider given in #{env}")
end
end
end

defp identity_provider_type_to_module, do: @identity_provider_type_to_module
end
64 changes: 19 additions & 45 deletions lib/livebook/hubs/dockerfile.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ defmodule Livebook.Hubs.Dockerfile do
deploy_all: boolean(),
docker_tag: String.t(),
clustering: nil | :auto | :dns,
zta_provider: atom() | nil,
zta_key: String.t() | nil
zta_provider: atom() | nil
}

@types %{
deploy_all: :boolean,
docker_tag: :string,
clustering: Ecto.ParameterizedType.init(Ecto.Enum, values: [:auto, :dns]),
zta_provider: :atom
}

@doc """
Builds the default Dockerfile configuration.
"""
Expand All @@ -24,8 +30,7 @@ defmodule Livebook.Hubs.Dockerfile do
deploy_all: false,
docker_tag: default_image.tag,
clustering: nil,
zta_provider: nil,
zta_key: nil
zta_provider: nil
}
end

Expand All @@ -37,8 +42,7 @@ defmodule Livebook.Hubs.Dockerfile do
%{
config_new()
| clustering: deployment_group.clustering,
zta_provider: deployment_group.zta_provider,
zta_key: deployment_group.zta_key
zta_provider: deployment_group.zta_provider
}
end

Expand All @@ -47,19 +51,8 @@ defmodule Livebook.Hubs.Dockerfile do
"""
@spec config_changeset(config(), map()) :: Ecto.Changeset.t()
def config_changeset(config, attrs \\ %{}) do
zta_types =
for provider <- Livebook.Config.identity_providers(),
do: provider.type

types = %{
deploy_all: :boolean,
docker_tag: :string,
clustering: Ecto.ParameterizedType.init(Ecto.Enum, values: [:auto, :dns]),
zta_provider: Ecto.ParameterizedType.init(Ecto.Enum, values: zta_types),
zta_key: :string
}

cast({config, types}, attrs, [:deploy_all, :docker_tag, :clustering, :zta_provider, :zta_key])
{config, @types}
|> cast(attrs, [:deploy_all, :docker_tag, :clustering, :zta_provider])
|> validate_required([:deploy_all, :docker_tag])
end

Expand Down Expand Up @@ -201,7 +194,7 @@ defmodule Livebook.Hubs.Dockerfile do
{Base.url_encode64(left, padding: false), "c_" <> Base.url_encode64(right, padding: false)}
end

defp format_hub_config("team", config, hub, hub_file_systems, used_secrets) do
defp format_hub_config("team", _config, hub, hub_file_systems, used_secrets) do
base_env =
"""
ARG TEAMS_KEY="#{hub.teams_key}"
Expand All @@ -225,14 +218,7 @@ defmodule Livebook.Hubs.Dockerfile do
"""
end

zta =
if zta_configured?(config) do
"""
ENV LIVEBOOK_IDENTITY_PROVIDER "#{config.zta_provider}:#{config.zta_key}"
"""
end

[base_env, secrets, file_systems, zta]
[base_env, secrets, file_systems]
|> Enum.reject(&is_nil/1)
|> Enum.join()
end
Expand Down Expand Up @@ -308,10 +294,6 @@ defmodule Livebook.Hubs.Dockerfile do
end
end

defp zta_configured?(config) do
config.zta_provider != nil and config.zta_key != nil
end

@doc """
Returns information for deploying Livebook Agent using Docker.
"""
Expand All @@ -331,13 +313,6 @@ defmodule Livebook.Hubs.Dockerfile do
"online:#{hub.hub_name}:#{hub.org_id}:#{hub.org_key_id}:#{agent_key.key}"}
]

hub_env =
if zta_configured?(config) do
[{"LIVEBOOK_IDENTITY_PROVIDER", "#{config.zta_provider}:#{config.zta_key}"}]
else
[]
end

{secret_key_base, cookie} = deterministic_skb_and_cookie(hub.teams_key)

clustering_env =
Expand All @@ -361,7 +336,7 @@ defmodule Livebook.Hubs.Dockerfile do
[]
end

%{image: image, env: base_image.env ++ env ++ hub_env ++ clustering_env}
%{image: image, env: base_image.env ++ env ++ clustering_env}
end

@doc """
Expand Down Expand Up @@ -418,19 +393,18 @@ defmodule Livebook.Hubs.Dockerfile do
end,
if app_settings.access_type == :public do
teams_link =
~s{<a class="font-medium underline text-gray-900 hover:no-underline" href="https://livebook.dev/teams?ref=LivebookApp" target="_blank">Livebook Teams</a>}
~s{<a class="font-medium underline text-gray-900 hover:no-underline" href="https://hexdocs.pm/livebook/authentication.html" target="_blank">Authentication</a>}

"This app has no password configuration and anyone with access to the server will be able" <>
" to use it. You may either configure a password or use #{teams_link} to add Zero Trust Authentication" <>
" to your deployed notebooks."
" to use it. See the documentation on #{teams_link} for more information."
end
]

"team" ->
[
if app_settings.access_type == :public and not zta_configured?(config) do
if app_settings.access_type == :public and config.zta_provider != :livebook_teams do
"This app has no password configuration and anyone with access to the server will be able" <>
" to use it. You may either configure a password or configure Zero Trust Authentication."
" to use it. You may either configure a password or enable authentication with Livebook Teams."
end
]
end
Expand Down
3 changes: 0 additions & 3 deletions lib/livebook/hubs/team_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,6 @@ defmodule Livebook.Hubs.TeamClient do
agent_keys: agent_keys,
clustering: nullify(deployment_group.clustering),
zta_provider: atomize(deployment_group.zta_provider),
zta_key: nullify(deployment_group.zta_key),
url: nullify(deployment_group.url)
}
end
Expand All @@ -453,7 +452,6 @@ defmodule Livebook.Hubs.TeamClient do
agent_keys: agent_keys,
clustering: nullify(deployment_group_created.clustering),
zta_provider: atomize(deployment_group_created.zta_provider),
zta_key: nullify(deployment_group_created.zta_key),
url: nullify(deployment_group_created.url)
}
end
Expand All @@ -470,7 +468,6 @@ defmodule Livebook.Hubs.TeamClient do
agent_keys: agent_keys,
clustering: atomize(deployment_group_updated.clustering),
zta_provider: atomize(deployment_group_updated.zta_provider),
zta_key: nullify(deployment_group_updated.zta_key),
url: nullify(deployment_group_updated.url)
}
end
Expand Down
30 changes: 24 additions & 6 deletions lib/livebook/teams/deployment_group.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,34 @@ defmodule Livebook.Teams.DeploymentGroup do
alias Livebook.Secrets.Secret
alias Livebook.Teams.AgentKey

@zta_providers Enum.map(Livebook.Config.identity_providers(), & &1.type)
@type t :: %__MODULE__{
id: String.t() | nil,
name: String.t() | nil,
url: String.t() | nil,
mode: :online | :offline,
clustering: :auto | :dns | nil,
hub_id: String.t() | nil,
secrets: Ecto.Schema.has_many(Secret.t()),
agent_keys: Ecto.Schema.has_many(AgentKey.t()),
zta_provider:
:basic_auth
| :cloudflare
| :google_iap
| :livebook_teams
| :tailscale
| nil
}

# TODO: Update this list to be only `:livebook_teams` in the future.
@zta_providers [:basic_auth, :cloudflare, :google_iap, :livebook_teams, :tailscale]

@primary_key {:id, :string, autogenerate: false}
embedded_schema do
field :name, :string
field :mode, Ecto.Enum, values: [:online, :offline], default: :online
field :hub_id, :string
field :clustering, Ecto.Enum, values: [:auto, :dns]
field :zta_provider, Ecto.Enum, values: @zta_providers
field :zta_key, :string
field :zta_provider, Ecto.Enum, values: @zta_providers, default: :livebook_teams
field :url, :string

has_many :secrets, Secret
Expand All @@ -24,7 +42,7 @@ defmodule Livebook.Teams.DeploymentGroup do
def changeset(deployment_group, attrs \\ %{}) do
changeset =
deployment_group
|> cast(attrs, [:id, :name, :mode, :hub_id, :clustering, :zta_provider, :zta_key, :url])
|> cast(attrs, [:id, :name, :mode, :hub_id, :clustering, :zta_provider, :url])
|> validate_required([:name, :mode])
|> update_change(:url, fn url ->
if url do
Expand All @@ -50,8 +68,8 @@ defmodule Livebook.Teams.DeploymentGroup do
end
end)

if get_field(changeset, :zta_provider) do
validate_required(changeset, [:zta_key])
if get_field(changeset, :mode) == :offline do
delete_change(changeset, :zta_provider)
else
changeset
end
Expand Down
1 change: 0 additions & 1 deletion lib/livebook/teams/requests.ex
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ defmodule Livebook.Teams.Requests do
mode: deployment_group.mode,
clustering: deployment_group.clustering,
zta_provider: deployment_group.zta_provider,
zta_key: deployment_group.zta_key,
url: deployment_group.url
}

Expand Down
6 changes: 0 additions & 6 deletions lib/livebook/zta.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,4 @@ defmodule Livebook.ZTA do
def put(name, value) do
:ets.insert(__MODULE__, [{name, value}])
end

def provider_name(nil), do: "None"

def provider_name(provider_type) do
Livebook.Config.zta_metadata(provider_type).name
end
end
Loading

0 comments on commit 473830a

Please sign in to comment.