Add a detailed Google Workspace setup guide and other docs (#2876)
- Added google workspace docs at `/kb/authenticate/google` - Updated in-product Provider creation form with more details and a link to docs - Fixed bg-color for unauthenticated layouts --------- Co-authored-by: Brian Manifold <bmanifold@gmail.com>
@@ -1100,4 +1100,39 @@ defmodule Web.CoreComponents do
|
||||
def translate_errors(errors, field) when is_list(errors) do
|
||||
for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts})
|
||||
end
|
||||
|
||||
@doc """
|
||||
This component is meant to be used for step by step instructions
|
||||
|
||||
ex.
|
||||
<.step>
|
||||
<:title>Step 1. Do Something</:title>
|
||||
<:content>
|
||||
Here are instructions for step 1...
|
||||
</:content>
|
||||
</.step>
|
||||
|
||||
<.step>
|
||||
<:title>Step 2. Do Another Thing</:title>
|
||||
<:content>
|
||||
Here are instructions for step 2...
|
||||
</:content>
|
||||
</.step>
|
||||
|
||||
"""
|
||||
slot :title, required: true
|
||||
slot :content, required: true
|
||||
|
||||
def step(assigns) do
|
||||
~H"""
|
||||
<div class="mb-6">
|
||||
<h2 class="mb-2 text-2xl tracking-tight font-bold text-neutral-900">
|
||||
<%= render_slot(@title) %>
|
||||
</h2>
|
||||
<div class="px-4">
|
||||
<%= render_slot(@content) %>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
>
|
||||
</script>
|
||||
</head>
|
||||
<body class="">
|
||||
<body class="bg-neutral-50">
|
||||
<%= @inner_content %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -14,7 +14,7 @@ defmodule Web.PageComponents do
|
||||
|
||||
def section(assigns) do
|
||||
~H"""
|
||||
<div class="mb-12 bg-white overflow-hidden shadow mx-5 rounded border px-6 pb-6">
|
||||
<div class="mb-6 bg-white overflow-hidden shadow mx-5 rounded border px-6 pb-6">
|
||||
<.header>
|
||||
<:title>
|
||||
<%= render_slot(@title) %>
|
||||
|
||||
@@ -3,7 +3,7 @@ defmodule Web.HomeHTML do
|
||||
|
||||
def home(assigns) do
|
||||
~H"""
|
||||
<section class="bg-neutral-50">
|
||||
<section>
|
||||
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto lg:py-0">
|
||||
<.logo />
|
||||
|
||||
|
||||
@@ -3,117 +3,227 @@ defmodule Web.Settings.IdentityProviders.GoogleWorkspace.Components do
|
||||
|
||||
def provider_form(assigns) do
|
||||
~H"""
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-12">
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
<div class="mb-4">
|
||||
<h2 class="mb-4 text-xl font-bold text-neutral-900">
|
||||
Step 1. Enable Admin SDK API
|
||||
</h2>
|
||||
Visit the following link to enable the Admin SDK API for your Google Workspace account:
|
||||
<a
|
||||
href="https://console.cloud.google.com/apis/library/admin.googleapis.com"
|
||||
class={link_style()}
|
||||
target="_blank"
|
||||
>
|
||||
https://console.cloud.google.com/apis/library/admin.googleapis.com
|
||||
</a>
|
||||
</div>
|
||||
<.step>
|
||||
<:title>Step 1. Create a new project in Google Cloud</:title>
|
||||
<:content>
|
||||
Visit the following link to create a new project to use for this integration:
|
||||
<a
|
||||
href="https://console.cloud.google.com/projectcreate"
|
||||
class={link_style()}
|
||||
target="_blank"
|
||||
>
|
||||
https://console.cloud.google.com/projectcreate
|
||||
</a>
|
||||
</:content>
|
||||
</.step>
|
||||
|
||||
<div class="mb-4">
|
||||
<h2 class="mb-4 text-xl font-bold text-neutral-900">
|
||||
Step 2. Configure OAuth consent screen
|
||||
</h2>
|
||||
<p class="mb-4">
|
||||
Ensure the following scopes are added to the OAuth client:
|
||||
</p>
|
||||
<.code_block
|
||||
:for={
|
||||
{name, scope} <- [
|
||||
openid: "openid",
|
||||
email: "email",
|
||||
profile: "profile",
|
||||
orgunit: "https://www.googleapis.com/auth/admin.directory.orgunit.readonly",
|
||||
group: "https://www.googleapis.com/auth/admin.directory.group.readonly",
|
||||
user: "https://www.googleapis.com/auth/admin.directory.user.readonly"
|
||||
]
|
||||
}
|
||||
id={"scope-#{name}"}
|
||||
class="w-full mb-4 whitespace-nowrap rounded"
|
||||
phx-no-format
|
||||
><%= scope %></.code_block>
|
||||
</div>
|
||||
<.step>
|
||||
<:title>Step 2. Enable Admin SDK API</:title>
|
||||
<:content>
|
||||
Visit the following link to enable the Admin SDK API for the project you just created:
|
||||
<a
|
||||
href="https://console.cloud.google.com/apis/library/admin.googleapis.com"
|
||||
class={link_style()}
|
||||
target="_blank"
|
||||
>
|
||||
https://console.cloud.google.com/apis/library/admin.googleapis.com
|
||||
</a>
|
||||
</:content>
|
||||
</.step>
|
||||
|
||||
<div class="mb-4">
|
||||
<h2 class="mb-4 text-xl font-bold text-neutral-900">
|
||||
Step 3: Create OAuth client
|
||||
</h2>
|
||||
<p class="mb-4">
|
||||
Ensure the OAuth client has following redirect URLs configured:
|
||||
</p>
|
||||
<.code_block
|
||||
:for={
|
||||
{type, redirect_url} <- [
|
||||
sign_in: url(~p"/#{@account.id}/sign_in/providers/#{@id}/handle_callback"),
|
||||
connect:
|
||||
url(
|
||||
~p"/#{@account.id}/settings/identity_providers/google_workspace/#{@id}/handle_callback"
|
||||
)
|
||||
]
|
||||
}
|
||||
id={"redirect_url-#{type}"}
|
||||
class="w-full mb-4 whitespace-nowrap rounded"
|
||||
phx-no-format
|
||||
><%= redirect_url %></.code_block>
|
||||
</div>
|
||||
<.step>
|
||||
<:title>Step 3. Configure OAuth consent screen</:title>
|
||||
<:content>
|
||||
<p class="mb-4">
|
||||
Visit the following link to configure the OAuth consent screen:
|
||||
<a
|
||||
href="https://console.cloud.google.com/apis/credentials/consent"
|
||||
class={link_style()}
|
||||
target="_blank"
|
||||
>
|
||||
https://console.cloud.google.com/apis/credentials/consent
|
||||
</a>
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Select <strong>Internal</strong> for the user type and click <strong>CREATE</strong>.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
On the next page, use the following values:
|
||||
</p>
|
||||
<ul class="ml-4 mb-4 list-disc list-inside">
|
||||
<li>
|
||||
<strong>App name</strong>: Firezone
|
||||
</li>
|
||||
<li>
|
||||
<strong>User support email</strong>: Your email address
|
||||
</li>
|
||||
<li>
|
||||
<strong>App logo</strong>:
|
||||
<.link
|
||||
href="https://www.firezone.dev/images/gco-oauth-screen-logo.png"
|
||||
class={link_style()}
|
||||
>
|
||||
Download here
|
||||
</.link>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Application home page</strong>:
|
||||
<.link href="https://www.firezone.dev" class={link_style()}>
|
||||
https://www.firezone.dev
|
||||
</.link>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Application privacy policy link</strong>:
|
||||
<.link href="https://www.firezone.dev/privacy-policy" class={link_style()}>
|
||||
https://www.firezone.dev/privacy-policy
|
||||
</.link>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Application terms of service link</strong>:
|
||||
<.link href="https://www.firezone.dev/terms" class={link_style()}>
|
||||
https://www.firezone.dev/terms
|
||||
</.link>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Authorized domains</strong>:
|
||||
<code class="px-1 py-0.5 text-sm bg-neutral-600 text-white">firezone.dev</code>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="mb-4">
|
||||
Click <strong>SAVE AND CONTINUE</strong>.
|
||||
</p>
|
||||
</:content>
|
||||
</.step>
|
||||
|
||||
<div class="mb-4">
|
||||
<h2 class="mb-4 text-xl font-bold text-neutral-900">
|
||||
Step 4. Configure client
|
||||
</h2>
|
||||
<.step>
|
||||
<:title>Step 4. Configure scopes</:title>
|
||||
<:content>
|
||||
<p class="mb-4">
|
||||
Click <strong>ADD OR REMOVE SCOPES</strong> and ensure the following scopes are added:
|
||||
</p>
|
||||
<.code_block
|
||||
id="oauth-scopes"
|
||||
class="w-full text-xs mb-4 whitespace-pre-line rounded"
|
||||
phx-no-format
|
||||
><%= scopes() %></.code_block>
|
||||
<p class="mb-4">
|
||||
Then click <strong>UPDATE</strong>.
|
||||
</p>
|
||||
</:content>
|
||||
</.step>
|
||||
|
||||
<.base_error form={@form} field={:base} />
|
||||
<.step>
|
||||
<:title>Step 5: Create client credentials</:title>
|
||||
<:content>
|
||||
<p class="mb-4">
|
||||
Go to the client credentials section and click <strong>CREATE CREDENTIALS</strong>
|
||||
to create new OAuth credentials.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Select <strong>OAuth client ID</strong>
|
||||
and then select <strong>Web application</strong>.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Use the following values on the next screen:
|
||||
</p>
|
||||
<ul class="ml-4 mb-4 list-disc list-inside">
|
||||
<li>
|
||||
<strong>Name</strong>: Firezone OAuth Client
|
||||
</li>
|
||||
<li>
|
||||
<strong>Authorized redirect URIs</strong>:
|
||||
<p class="mt-4">
|
||||
<.code_block
|
||||
:for={
|
||||
{type, redirect_url} <- [
|
||||
sign_in: url(~p"/#{@account.id}/sign_in/providers/#{@id}/handle_callback"),
|
||||
connect:
|
||||
url(
|
||||
~p"/#{@account.id}/settings/identity_providers/google_workspace/#{@id}/handle_callback"
|
||||
)
|
||||
]
|
||||
}
|
||||
id={"redirect_url-#{type}"}
|
||||
class="w-full mb-4 text-xs whitespace-nowrap rounded"
|
||||
phx-no-format
|
||||
><%= redirect_url %></.code_block>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="mb-4">
|
||||
Click <strong>CREATE</strong>. Copy the <strong>Client ID</strong>
|
||||
and <strong>Client secret</strong>
|
||||
values from the next screen.
|
||||
</p>
|
||||
</:content>
|
||||
</.step>
|
||||
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div>
|
||||
<.input
|
||||
label="Name"
|
||||
autocomplete="off"
|
||||
field={@form[:name]}
|
||||
placeholder="Name this identity provider"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
A friendly name for this identity provider. This will be displayed to end-users.
|
||||
</p>
|
||||
<.step>
|
||||
<:title>Step 6. Configure Firezone</:title>
|
||||
<:content>
|
||||
<.base_error form={@form} field={:base} />
|
||||
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div>
|
||||
<.input
|
||||
label="Name"
|
||||
autocomplete="off"
|
||||
field={@form[:name]}
|
||||
placeholder="Name this identity provider"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
A friendly name for this identity provider. This will be displayed to end-users.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<.inputs_for :let={adapter_config_form} field={@form[:adapter_config]}>
|
||||
<div>
|
||||
<.input
|
||||
label="Client ID"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:client_id]}
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
The Client ID from the previous step.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Client secret"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:client_secret]}
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
The Client secret from the previous step.
|
||||
</p>
|
||||
</div>
|
||||
</.inputs_for>
|
||||
</div>
|
||||
|
||||
<.inputs_for :let={adapter_config_form} field={@form[:adapter_config]}>
|
||||
<div>
|
||||
<.input
|
||||
label="Client ID"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:client_id]}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Client secret"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:client_secret]}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</.inputs_for>
|
||||
</div>
|
||||
|
||||
<.submit_button>
|
||||
Connect Identity Provider
|
||||
</.submit_button>
|
||||
</div>
|
||||
<.submit_button>
|
||||
Connect Identity Provider
|
||||
</.submit_button>
|
||||
</:content>
|
||||
</.step>
|
||||
</.form>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def scopes do
|
||||
"""
|
||||
openid
|
||||
profile
|
||||
email
|
||||
https://www.googleapis.com/auth/admin.directory.orgunit.readonly
|
||||
https://www.googleapis.com/auth/admin.directory.group.readonly
|
||||
https://www.googleapis.com/auth/admin.directory.user.readonly
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,6 +39,11 @@ defmodule Web.Settings.IdentityProviders.GoogleWorkspace.New do
|
||||
<:title>
|
||||
Add a new Google Workspace Identity Provider
|
||||
</:title>
|
||||
<:help>
|
||||
For a more detailed guide on setting up Firezone with Google Workspace, please <.link class={
|
||||
link_style()
|
||||
}>refer to our documentation</.link>.
|
||||
</:help>
|
||||
<:content>
|
||||
<.provider_form account={@account} id={@id} form={@form} />
|
||||
</:content>
|
||||
|
||||
@@ -48,13 +48,6 @@ defmodule Web.Settings.IdentityProviders.GoogleWorkspace.Show do
|
||||
>
|
||||
Enable Identity Provider
|
||||
</.button>
|
||||
<.button
|
||||
:if={is_nil(@provider.disabled_at)}
|
||||
phx-click="disable"
|
||||
data-confirm="Are you sure want to disable this provider? All authorizations will be revoked and actors won't be able to use it to access Firezone."
|
||||
>
|
||||
Disable Identity Provider
|
||||
</.button>
|
||||
<% end %>
|
||||
</:action>
|
||||
<:action :if={is_nil(@provider.deleted_at)}>
|
||||
@@ -104,6 +97,15 @@ defmodule Web.Settings.IdentityProviders.GoogleWorkspace.Show do
|
||||
|
||||
<.danger_zone :if={is_nil(@provider.deleted_at)}>
|
||||
<:action>
|
||||
<.button
|
||||
:if={is_nil(@provider.disabled_at)}
|
||||
style="warning"
|
||||
phx-click="disable"
|
||||
icon="hero-no-symbol"
|
||||
data-confirm="Are you sure want to disable this provider? Users will no longer be able to sign in with this provider and user / group sync will be paused."
|
||||
>
|
||||
Disable Identity Provider
|
||||
</.button>
|
||||
<.delete_button
|
||||
data-confirm="Are you sure want to delete this provider along with all related data?"
|
||||
phx-click="delete"
|
||||
|
||||
@@ -3,116 +3,115 @@ defmodule Web.Settings.IdentityProviders.OpenIDConnect.Components do
|
||||
|
||||
def provider_form(assigns) do
|
||||
~H"""
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-12">
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
<div class="mb-4">
|
||||
<h2 class="mb-4 text-xl font-bold text-neutral-900">
|
||||
Step 1. Create OAuth app in your identity provider
|
||||
</h2>
|
||||
Please make sure that following scopes are added to the OAuth application: <.code_block
|
||||
:for={scope <- [:openid, :email, :profile]}
|
||||
id={"scope-#{scope}"}
|
||||
class="w-full mb-4 whitespace-nowrap rounded"
|
||||
phx-no-format
|
||||
><%= scope %></.code_block> Please make sure that OAuth client has following redirect URL's whitelisted: <.code_block
|
||||
:for={
|
||||
{type, redirect_url} <- [
|
||||
sign_in: url(~p"/#{@account.id}/sign_in/providers/#{@id}/handle_callback"),
|
||||
connect:
|
||||
url(
|
||||
~p"/#{@account.id}/settings/identity_providers/openid_connect/#{@id}/handle_callback"
|
||||
)
|
||||
]
|
||||
}
|
||||
id={"redirect_url-#{type}"}
|
||||
class="w-full mb-4 whitespace-nowrap rounded"
|
||||
phx-no-format
|
||||
><%= redirect_url %></.code_block>
|
||||
</div>
|
||||
<.step>
|
||||
<:title>Step 1. Create OAuth app in your identity provider</:title>
|
||||
<:content>
|
||||
Please make sure that following scopes are added to the OAuth application: <.code_block
|
||||
:for={scope <- [:openid, :email, :profile]}
|
||||
id={"scope-#{scope}"}
|
||||
class="w-full mb-4 whitespace-nowrap rounded"
|
||||
phx-no-format
|
||||
><%= scope %></.code_block> Please make sure that OAuth client has following redirect URL's whitelisted: <.code_block
|
||||
:for={
|
||||
{type, redirect_url} <- [
|
||||
sign_in: url(~p"/#{@account.id}/sign_in/providers/#{@id}/handle_callback"),
|
||||
connect:
|
||||
url(
|
||||
~p"/#{@account.id}/settings/identity_providers/openid_connect/#{@id}/handle_callback"
|
||||
)
|
||||
]
|
||||
}
|
||||
id={"redirect_url-#{type}"}
|
||||
class="w-full mb-4 whitespace-nowrap rounded"
|
||||
phx-no-format
|
||||
><%= redirect_url %></.code_block>
|
||||
</:content>
|
||||
</.step>
|
||||
|
||||
<div class="mb-4">
|
||||
<h2 class="mb-4 text-xl font-bold text-neutral-900">
|
||||
2. Configure client
|
||||
</h2>
|
||||
<.step>
|
||||
<:title>Step 2. Configure client</:title>
|
||||
<:content>
|
||||
<.base_error form={@form} field={:base} />
|
||||
|
||||
<.base_error form={@form} field={:base} />
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div>
|
||||
<.input
|
||||
label="Name"
|
||||
autocomplete="off"
|
||||
field={@form[:name]}
|
||||
placeholder="Name this identity provider"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
A friendly name for this identity provider. This will be displayed to end-users.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div>
|
||||
<.input
|
||||
label="Name"
|
||||
autocomplete="off"
|
||||
field={@form[:name]}
|
||||
placeholder="Name this identity provider"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
A friendly name for this identity provider. This will be displayed to end-users.
|
||||
</p>
|
||||
<.inputs_for :let={adapter_config_form} field={@form[:adapter_config]}>
|
||||
<div>
|
||||
<.input
|
||||
label="Response Type"
|
||||
field={adapter_config_form[:response_type]}
|
||||
placeholder="code"
|
||||
value="code"
|
||||
disabled
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
Firezone currently only supports <code>code</code> flows.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Scopes"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:scope]}
|
||||
placeholder="OpenID Connect scopes to request"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
A space-delimited list of scopes to request from your identity provider. In most cases you shouldn't need to change this.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Client ID"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:client_id]}
|
||||
placeholder="Client ID from your IdP"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Client secret"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:client_secret]}
|
||||
placeholder="Client Secret from your IdP"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Discovery URL"
|
||||
field={adapter_config_form[:discovery_document_uri]}
|
||||
placeholder=".well-known URL for your IdP"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</.inputs_for>
|
||||
</div>
|
||||
|
||||
<.inputs_for :let={adapter_config_form} field={@form[:adapter_config]}>
|
||||
<div>
|
||||
<.input
|
||||
label="Response Type"
|
||||
field={adapter_config_form[:response_type]}
|
||||
placeholder="code"
|
||||
value="code"
|
||||
disabled
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
Firezone currently only supports <code>code</code> flows.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Scopes"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:scope]}
|
||||
placeholder="OpenID Connect scopes to request"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
A space-delimited list of scopes to request from your identity provider. In most cases you shouldn't need to change this.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Client ID"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:client_id]}
|
||||
placeholder="Client ID from your IdP"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Client secret"
|
||||
autocomplete="off"
|
||||
field={adapter_config_form[:client_secret]}
|
||||
placeholder="Client Secret from your IdP"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<.input
|
||||
label="Discovery URL"
|
||||
field={adapter_config_form[:discovery_document_uri]}
|
||||
placeholder=".well-known URL for your IdP"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</.inputs_for>
|
||||
</div>
|
||||
|
||||
<.submit_button>
|
||||
Connect Identity Provider
|
||||
</.submit_button>
|
||||
</div>
|
||||
<.submit_button>
|
||||
Connect Identity Provider
|
||||
</.submit_button>
|
||||
</:content>
|
||||
</.step>
|
||||
</.form>
|
||||
</div>
|
||||
"""
|
||||
|
||||
@@ -40,7 +40,7 @@ defmodule Web.SignIn do
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<section class="bg-neutral-50">
|
||||
<section>
|
||||
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto lg:py-0">
|
||||
<.logo />
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ defmodule Web.SignIn.Email do
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<section class="bg-neutral-50">
|
||||
<section>
|
||||
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto lg:py-0">
|
||||
<.logo />
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ defmodule Web.SignUp do
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<section class="bg-neutral-50">
|
||||
<section>
|
||||
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto lg:py-0">
|
||||
<.logo />
|
||||
|
||||
|
||||
@@ -43,6 +43,19 @@ defmodule Web.Sites.NewToken do
|
||||
<:title>
|
||||
Deploy a new Gateway
|
||||
</:title>
|
||||
<:help>
|
||||
Gateways require outbound access to <code
|
||||
class="text-sm bg-neutral-600 text-white px-1 py-0.5 rounded"
|
||||
phx-no-format
|
||||
>api.firezone.dev:443</code> only. <strong>No inbound firewall rules</strong>
|
||||
are required or recommended.
|
||||
</:help>
|
||||
<:help>
|
||||
<.link
|
||||
href="http://www.firezone.dev/kb/deploy/gateways?utm_source=product"
|
||||
class="text-accent-500 hover:underline"
|
||||
>Read the gateway deployment guide for more detailed instructions</.link>.
|
||||
</:help>
|
||||
<:content>
|
||||
<div class="py-8 px-4 mx-auto max-w-2xl lg:py-16">
|
||||
<div class="text-xl mb-4">
|
||||
|
||||
BIN
website/public/images/gcp-allow.png
Normal file
|
After Width: | Height: | Size: 150 KiB |
BIN
website/public/images/gcp-create-credentials.png
Normal file
|
After Width: | Height: | Size: 569 KiB |
BIN
website/public/images/gcp-create-project.png
Normal file
|
After Width: | Height: | Size: 412 KiB |
BIN
website/public/images/gcp-creds-web.png
Normal file
|
After Width: | Height: | Size: 740 KiB |
BIN
website/public/images/gcp-enable-admin-api.png
Normal file
|
After Width: | Height: | Size: 445 KiB |
BIN
website/public/images/gcp-oauth-consent-screen.png
Normal file
|
After Width: | Height: | Size: 518 KiB |
BIN
website/public/images/gcp-oauth-credentials.png
Normal file
|
After Width: | Height: | Size: 730 KiB |
BIN
website/public/images/gcp-oauth-screen-2.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
website/public/images/gcp-oauth-screen-logo.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
website/public/images/gcp-oauth-summary.png
Normal file
|
After Width: | Height: | Size: 925 KiB |
BIN
website/public/images/gcp-scopes-continue.png
Normal file
|
After Width: | Height: | Size: 878 KiB |
BIN
website/public/images/gcp-update-scopes-2.png
Normal file
|
After Width: | Height: | Size: 685 KiB |
BIN
website/public/images/gcp-update-scopes.png
Normal file
|
After Width: | Height: | Size: 660 KiB |
@@ -10,14 +10,17 @@ high-availability deployments.
|
||||
|
||||
## How versioning works in Firezone
|
||||
|
||||
Firezone uses a semantic versioning scheme in the standard
|
||||
`MAJOR`.`MINOR`.`PATCH` format with the following structure:
|
||||
Firezone uses a simple versioning scheme with the following structure:
|
||||
|
||||
| Version type | Example | Explanation |
|
||||
| ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `MAJOR` | `1` | Marketing version. Updates to this version generally constitute a new architecture or product. Updated every few years on average. |
|
||||
| `MINOR` | `20231001` | API version. Clients and gateways **must** be the same API version to function together. The Firezone admin portal supports the latest **two** API versions at the same time. Updated every 6 months on average. |
|
||||
| `PATCH` | `11` | Patch version. Represents backwards-compatible bug fixes and updates that are generally recommended for all users. Updated on average every week. |
|
||||
`MARKETING`.`API_DATE`.`PATCH`
|
||||
|
||||
Each of these fields is described below.
|
||||
|
||||
| Version field | Example | Explanation |
|
||||
| ------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `MARKETING` | `1` | Marketing version. Updates to this version generally constitute a new architecture or product. Updated every few years on average. |
|
||||
| `API_DATE` | `20231001` | API version. Clients and gateways **must** be the same API version to function together. The Firezone admin portal supports the latest **two** API versions at the same time. Updated every 6 months on average. |
|
||||
| `PATCH` | `11` | Patch version. Represents backwards-compatible bug fixes and updates that are generally recommended for all users. Updated on average every week. |
|
||||
|
||||
All Firezone components follow the structure above, so it is trivial to
|
||||
determine which clients work with which gateways and for how long.
|
||||
@@ -51,7 +54,7 @@ Gateways deployed in the same site will automatically
|
||||
one-by-one, clients connected to the gateway being upgraded will automatically
|
||||
reconnect to an available gateway.
|
||||
|
||||
Currently the failover timeout is maximum 120 seconds, so upgrades should be
|
||||
Currently the failover timeout is maximum 25 seconds, so upgrades should be
|
||||
performed during a scheduled maintenance window to ensure minimal disruption.
|
||||
Other than a possible short-term connection interruption to in-use resources,
|
||||
users won't be impacted by upgrading high-availability gateways.
|
||||
|
||||
6
website/src/app/kb/authenticate/google/_page.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
"use client";
|
||||
import Content from "./readme.mdx";
|
||||
|
||||
export default function _Page() {
|
||||
return <Content />;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import Content from "./readme.mdx";
|
||||
import _Page from "./_page";
|
||||
import { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -7,5 +7,5 @@ export const metadata: Metadata = {
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
return <Content />;
|
||||
return <_Page />;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import Alert from "@/components/DocsAlert";
|
||||
import SupportOptions from "@/components/SupportOptions";
|
||||
import PlanBadge from "@/components/PlanBadge";
|
||||
import Image from "next/image";
|
||||
|
||||
<PlanBadge plans={["enterprise"]} />
|
||||
|
||||
@@ -24,7 +26,7 @@ Google Workspace for your Firezone Enterprise account.
|
||||
## Overview
|
||||
|
||||
The Firezone Google Workspace connector integrates with Google's identity APIs
|
||||
to support user authentication and automatic user/group sync.
|
||||
to support user authentication and user / group sync.
|
||||
|
||||
Users, groups, and organizational units are synced every few minutes to ensure
|
||||
that your Firezone account remains up-to-date with the latest identity data from
|
||||
@@ -33,10 +35,224 @@ your Google Workspace account.
|
||||
|
||||
## Setup
|
||||
|
||||
To set up the Google workspace connector, go to `Settings` ->
|
||||
`Identity Providers` -> `Add Identity Provider` and follow the prompts from
|
||||
there.
|
||||
|
||||
Setting up the Google Workspace connector is similar to the process of setting
|
||||
up a universal OIDC connector. The main difference is the addition of a few
|
||||
extra scopes needed to enable user/group sync.
|
||||
|
||||
To setup the Google Workspace connector, follow the steps below.
|
||||
|
||||
### Step 1: Create a new project in Google Cloud
|
||||
|
||||
<Alert
|
||||
color="info"
|
||||
html={`
|
||||
You may skip this step and proceed directly to
|
||||
<a href="#step-2-enable-the-admin-sdk-api" class="hover:underline text-accent-500">
|
||||
Step 2</a> if you already have a GCP project you'd like to use with Firezone.
|
||||
`}
|
||||
/>
|
||||
|
||||
[Go here to create a new project](https://console.cloud.google.com/projectcreate)
|
||||
in your Google Cloud account and fill in the following fields:
|
||||
|
||||
- **Project name**: `Firezone Connector`
|
||||
- **Organization**: Select the appropriate organization that contains the users
|
||||
and groups you wish to integrate with Firezone.
|
||||
- **Location**: Select the appropriate organization to place this project under.
|
||||
|
||||
Click **CREATE** after you've filled in the fields above.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-create-project.png"
|
||||
alt="Create project in GCP"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
### Step 2: Enable the Admin SDK API
|
||||
|
||||
[Visit this link](https://console.cloud.google.com/apis/library/admin.googleapis.com)
|
||||
to enable the Admin SDK API for the project you just created in Step 1.
|
||||
|
||||
**Important**: Ensure the **Firezone Connector** project you created in Step 1
|
||||
is selected before clicking the "ENABLE" button.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-enable-admin-api.png"
|
||||
alt="Enable Admin SDK API"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
### Step 3: Configure the OAuth consent screen
|
||||
|
||||
[Click here](https://console.cloud.google.com/apis/credentials/consent) to
|
||||
configure the OAuth consent screen for the project you created in Step 1.
|
||||
|
||||
**Important**: Select "Internal" for User type. Select "External" may allow
|
||||
external users to login to your Firezone account.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-oauth-consent-screen.png"
|
||||
alt="Enable Admin SDK API"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
Click **CREATE**.
|
||||
|
||||
On the next page, enter the following information:
|
||||
|
||||
- **App name**: `Firezone`
|
||||
- **User support email**: Your or your company's IT support email address.
|
||||
- **App logo** (optional):
|
||||
[Download the Firezone logo here](/images/gcp-oauth-screen-logo.png) to use
|
||||
for this consent screen.
|
||||
- **Application home page**: `https://www.firezone.dev`
|
||||
- **Application privacy policy link**: `https://www.firezone.dev/privacy-policy`
|
||||
- **Application terms of service link**: `https://www.firezone.dev/terms`
|
||||
- **Authorized domains**: Click "ADD DOMAIN" and enter `firezone.dev`
|
||||
- **Developer contact information**: Enter the same email you used above, e.g.
|
||||
`it-support@company.com`
|
||||
|
||||
<Image
|
||||
src="/images/gcp-oauth-screen-2.png"
|
||||
alt="Add app info"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
Click **SAVE AND CONTINUE**.
|
||||
|
||||
### Step 4: Configure scopes
|
||||
|
||||
OAuth scopes determine what information the Firezone connector is allowed to
|
||||
receive when a user authenticates. Firezone requires the following scopes to
|
||||
authenticate users and sync users and groups with your Google Workspace account:
|
||||
|
||||
- `openid`: Reserved scope required by all OpenID Connect integrations.
|
||||
- `profile`: Provides information such as the user's username, given name,
|
||||
surname, and so forth.
|
||||
- `email`: The user's email address.
|
||||
- `https://www.googleapis.com/auth/admin.directory.orgunit.readonly`: Required
|
||||
to sync Organization Units.
|
||||
- `https://www.googleapis.com/auth/admin.directory.group.readonly`: Required to
|
||||
sync Groups.
|
||||
- `https://www.googleapis.com/auth/admin.directory.user.readonly`: Required to
|
||||
sync Users.
|
||||
|
||||
```text
|
||||
openid
|
||||
profile
|
||||
email
|
||||
https://www.googleapis.com/auth/admin.directory.orgunit.readonly
|
||||
https://www.googleapis.com/auth/admin.directory.group.readonly
|
||||
https://www.googleapis.com/auth/admin.directory.user.readonly
|
||||
```
|
||||
|
||||
Click **ADD OR REMOVE SCOPES** and copy-paste the above scopes into the
|
||||
**Manually add scopes** field.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-update-scopes.png"
|
||||
alt="Update scopes"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
Then click **UPDATE** to make sure they're applied.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-update-scopes-2.png"
|
||||
alt="Update scopes"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
<Image
|
||||
src="/images/gcp-scopes-continue.png"
|
||||
alt="Scopes continue"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
Ensure your Scopes configuration looks like the screenshot above, then click
|
||||
**SAVE AND CONTINUE**.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-oauth-summary.png"
|
||||
alt="Scopes continue"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
Your OAuth app summary should look similar to the screenshot above.
|
||||
|
||||
### Step 5: Create client credentials
|
||||
|
||||
Next, you'll need to add OAuth credentials to allow Firezone to connect to your
|
||||
Google Workspace account.
|
||||
|
||||
Head to
|
||||
[the Credentials section](https://console.cloud.google.com/apis/credentials) and
|
||||
click **CREATE CREDENTIALS** to create new OAuth credentials. Be sure to select
|
||||
"OAuth client ID" in the dropdown menu.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-create-credentials.png"
|
||||
alt="Create OAuth credentials"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
On the next screen, select **Web application**, then use the following
|
||||
information for the remain fields:
|
||||
|
||||
- **Name**: `Firezone OAuth Client`
|
||||
- **Authorized redirect URIs**: Click **ADD URI**, and enter the two redirect
|
||||
URIs shown on the Google Workspace identity provider setup screen in your
|
||||
Firezone admin dashboard
|
||||
(`Settings -> Identity Providers -> Add Identity Provider -> Google Workspace -> Configure`).
|
||||
|
||||
<Image
|
||||
src="/images/gcp-creds-web.png"
|
||||
alt="Web application credentials"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
Click **CREATE**.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-oauth-credentials.png"
|
||||
alt="Web application credentials"
|
||||
width={1200}
|
||||
height={1200}
|
||||
/>
|
||||
|
||||
**Important**: Make sure to save the `Client ID` and `Client secret` fields in a
|
||||
safe place as they won't be shown again.
|
||||
|
||||
### Step 6: Enter `Client ID` and `Client secret` in Firezone
|
||||
|
||||
Go back to the Firezone admin dashboard, and enter the `Client ID` and
|
||||
`Client secret` you copied from the previous step in the appropriate fields in
|
||||
"Create Identity Provider" form.
|
||||
|
||||
Finally, click **Connect Identity Provider** and click **Allow** when Google
|
||||
prompts you.
|
||||
|
||||
<Image
|
||||
src="/images/gcp-allow.png"
|
||||
alt="Allow admin access"
|
||||
width={400}
|
||||
height={400}
|
||||
className="mx-auto"
|
||||
/>
|
||||
|
||||
If you get successfully redirected back to your Firezone admin dashboard, you're
|
||||
done! Your Google Workspace connector is now successfully configured. Users in
|
||||
your organization can now authenticate to Firezone using this connector and user
|
||||
/ group sync will occur every few minutes.
|
||||
|
||||
<SupportOptions />
|
||||
|
||||
@@ -61,10 +61,10 @@ Two or more Gateways deployed in the same site will automatically fail over and
|
||||
load balance for each other.
|
||||
|
||||
When the portal detects a particular gateway is unhealthy, it will stop using it
|
||||
for new connection requests to resources in the site. Fail over takes around 60
|
||||
to 120 seconds for clients to time out their existing gateway connections and
|
||||
fail over to a healthy one. During this time, connection to resources will be
|
||||
interrupted, so it's important to plan gateway downtime appropriately.
|
||||
for new connection requests to resources in the site. Fail over takes up to 25
|
||||
seconds for clients to time out their existing gateway connections and fail over
|
||||
to a healthy one. During this time, connection to resources will be interrupted,
|
||||
so it's important to plan gateway downtime appropriately.
|
||||
|
||||
## Load balancing
|
||||
|
||||
|
||||
@@ -58,9 +58,20 @@ enter it in to the form on the sign-in page.
|
||||
When you log in to the admin portal, you'll land on the Sites page. The first
|
||||
step will be to create a Site by clicking the 'Add Site' button. We'll
|
||||
auto-generate a name for the site, but you should consider renaming it something
|
||||
relevant like `Production`, `US-West`, or `Chicago-office`. After the site is
|
||||
created, you'll be forwarded to the Site Details page where you can continue the
|
||||
setup process.
|
||||
relevant like `Production`, `US-West`, or `Chicago-office`.
|
||||
|
||||
When creating a Site, you're presented with the option to select the routing
|
||||
policy. Firezone uses industry-standard techniques to automatically holepunch
|
||||
direct, peer-to-peer connections between clients and gateways. In nearly all
|
||||
cases, this works fine, but in certain hostile network environments, a Relay
|
||||
must be used to ensure connectivity. Select `Firezone-managed Relays` to allow
|
||||
encrypted packets to traverse Firezone's managed global relay network, or select
|
||||
`Direct only` to force all packets to flow peer-to-peer _only_. Keep in mind
|
||||
`Direct only` can prevent connections in some rare circumstances based on the
|
||||
NAT topology of your gateway environment.
|
||||
|
||||
After the site is created, you'll be forwarded to the Site Details page where
|
||||
you can continue the setup process.
|
||||
|
||||
### Deploy a Gateway
|
||||
|
||||
|
||||