Packages
livebook
0.15.2
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook/zta.ex
defmodule Livebook.ZTA do
@moduledoc """
Enable zero-trust authentication within your Plug/Phoenix application.
The following ZTA providers are supported:
* Livebook.ZTA.Cloudflare
* Livebook.ZTA.GoogleIAP
* Livebook.ZTA.Tailscale
We also support the following providers for dev/test/staging:
* Livebook.ZTA.BasicAuth - HTTP basic authentication with a single user-pass
* Livebook.ZTA.PassThrough - always succeeds with no metadata
You can find documentation for setting up these providers under [Livebook's
authentication section in the sidebar](https://hexdocs.pm/livebook/).
## Usage
First you must add the ZTA provider of your choice to your supervision tree:
{Livebook.ZTA.GoogleIAP, name: :google_iap, identity_key: "foobar"}
where the `identity_key` is the identity provider specific key.
Then you can use the provider `c:authenticate/3` callback to authenticate
users on every request:
plug :zta
def zta(conn, _opts) do
case Livebook.ZTA.GoogleIAP.authenticate(conn, :google_iap) do
# The provider is redirecting somewhere for follow up
{%{halted: true} = conn, nil} ->
conn
# Authentication failed
{%{halted: false} = conn, nil} ->
send_resp(conn, 401, "Unauthorized")
# Authentication succeeded
{conn, metadata} ->
put_session(conn, :user_metadata, metadata)
end
end
Each provider may have specific optoins supported on `authenticate/3`.
""" && false
@type name :: atom()
@typedoc """
A metadata of keys returned by zero-trust authentication provider.
The following keys are supported:
* `:id` - a string that uniquely identifies the user
* `:name` - the user name
* `:email` - the user email
* `:payload` - the provider payload
Note that none of the keys are required. The metadata returned depends
on the provider.
"""
@type metadata :: %{
optional(:id) => String.t(),
optional(:name) => String.t(),
optional(:email) => String.t(),
optional(:payload) => map()
}
@doc """
Each provider must specify a child specification for its processes.
The `:name` and `:identity_key` keys are expected.
"""
@callback child_spec(name: name(), identity_key: String.t()) :: Supervisor.child_spec()
@doc """
Authenticates against the given name.
It will return one of:
* `{non_halted_conn, nil}` - the authentication failed and you must
halt the connection and render the appropriate report
* `{halted_conn, nil}` - the authentication failed and the connection
was modified accordingly to request the credentials
* `{non_halted_conn, metadata}` - the authentication succeed and the
following metadata about the user is available
"""
@callback authenticate(name(), Plug.Conn.t(), keyword()) :: {Plug.Conn.t(), metadata() | nil}
@doc false
def init do
:ets.new(__MODULE__, [:named_table, :public, :set, read_concurrency: true])
end
def get(name) do
:ets.lookup_element(__MODULE__, name, 2)
end
def put(name, value) do
:ets.insert(__MODULE__, [{name, value}])
end
end