Phoenix LiveView + Postgres + Fly.io security playbook

Updated

Phoenix on Fly is a high-performance stack for real-time AI apps. Security boundaries: channel topic auth, LiveView handle_event authorization, JWT verification with explicit alg.

What breaks on this stack

Channel join without authorize_user

join/3 without explicit user check lets users join arbitrary topics.

Read the guide →

handle_event without authz on target

LiveView handle_event mutating DB without checking caller's authz on the target — BOLA.

Read the guide →

JWT verification without alg pin

Verify with explicit algorithm + issuer + audience.

Read the guide →

Fly Postgres credentials in mix.exs

Use fly secrets, never commit to mix config.

Read the guide →

Pre-ship checklist

  • channel join/3 authorize_user
  • handle_event ownership check
  • JWT verifier explicit alg
  • Fly secrets for DB creds
  • Phoenix CSRF token on form events
  • BroadcasterScopedToUser pattern

Starter config

# lib/my_app_web/channels/user_channel.ex
defmodule MyAppWeb.UserChannel do
  use Phoenix.Channel
  def join("user:" <> user_id, _params, socket) do
    if to_string(socket.assigns.current_user.id) == user_id do
      {:ok, socket}
    else
      {:error, %{reason: "unauthorized"}}
    end
  end
end