Integrate WorkOS AuthKit with Elixir/Phoenix applications. Server-side authentication with Phoenix controllers and routes.
Install
npx skillscat add workos/cli/workos-elixir Install via the SkillsCat registry.
WorkOS AuthKit for Elixir (Phoenix)
Step 1: Fetch SDK Documentation (BLOCKING)
STOP. Do not proceed until complete.
WebFetch: https://raw.githubusercontent.com/workos/workos-elixir/main/README.md
The README is the source of truth for SDK API usage. If this skill conflicts with README, follow README.
Step 2: Pre-Flight Validation
Project Structure
- Confirm
mix.exsexists - Read
mix.exsto extract the app name (look forapp: :my_appinproject/0) - Confirm
lib/{app}_web/router.exexists (Phoenix project marker) - Confirm
config/runtime.exsexists
Determine App Name
The app name from mix.exs determines all file paths. For example, if app: :my_app:
- Web module:
lib/my_app_web/ - Router:
lib/my_app_web/router.ex - Controllers:
lib/my_app_web/controllers/
Environment Variables
Check .env.local for:
WORKOS_API_KEY- starts withsk_WORKOS_CLIENT_ID- starts withclient_
Step 3: Install SDK
Add the workos package to mix.exs dependencies:
defp deps do
[
# ... existing deps
{:workos, "~> 1.0"}
]
endThen run:
mix deps.getVerify: Check that mix deps.get completed successfully (exit code 0).
Step 4: Configure WorkOS
Add WorkOS configuration to config/runtime.exs:
config :workos,
api_key: System.get_env("WORKOS_API_KEY"),
client_id: System.get_env("WORKOS_CLIENT_ID")This ensures credentials are loaded from environment variables at runtime, not compiled into the release.
Step 5: Create Auth Controller
Prerequisite: Verify {AppName}Web module exists
The controller uses use {AppName}Web, :controller. Confirm lib/{app}_web.ex exists and defines the :controller macro. If it doesn't exist (minimal Phoenix projects may lack it), create it:
defmodule {AppName}Web do
def controller do
quote do
use Phoenix.Controller, formats: [:html, :json]
import Plug.Conn
end
end
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
endCreate controller
Create lib/{app}_web/controllers/auth_controller.ex:
defmodule {AppName}Web.AuthController do
use {AppName}Web, :controller
def sign_in(conn, _params) do
client_id = Application.get_env(:workos, :client_id)
redirect_uri = "http://localhost:4000/auth/callback"
authorization_url = WorkOS.UserManagement.get_authorization_url(%{
provider: "authkit",
client_id: client_id,
redirect_uri: redirect_uri
})
case authorization_url do
{:ok, url} -> redirect(conn, external: url)
{:error, reason} -> conn |> put_status(500) |> text("Auth error: #{inspect(reason)}")
end
end
def callback(conn, %{"code" => code}) do
client_id = Application.get_env(:workos, :client_id)
case WorkOS.UserManagement.authenticate_with_code(%{
code: code,
client_id: client_id
}) do
{:ok, auth_response} ->
conn
|> put_session(:user, auth_response.user)
|> redirect(to: "/")
{:error, reason} ->
conn |> put_status(401) |> text("Authentication failed: #{inspect(reason)}")
end
end
def sign_out(conn, _params) do
conn
|> clear_session()
|> redirect(to: "/")
end
endIMPORTANT: Adapt the module name and API calls based on the README. The WorkOS Elixir SDK API may differ from the pseudocode above. Always follow the README for exact function names, parameter shapes, and return types.
Step 6: Add Routes
Add auth routes to lib/{app}_web/router.ex. Add these routes inside or outside the existing pipeline scope as appropriate:
scope "/auth", {AppName}Web do
pipe_through :browser
get "/sign-in", AuthController, :sign_in
get "/callback", AuthController, :callback
post "/sign-out", AuthController, :sign_out
endStep 7: Verification
Run the following to confirm the integration compiles:
mix compileIf compilation fails:
- Read the error message carefully
- Check that the WorkOS SDK module names match what's in the README
- Verify the app name is consistent across all files
- Fix the issue and re-run
mix compile
Error Recovery
"could not compile dependency :workos"
- Check Elixir version compatibility (1.15+ recommended)
- Try
mix deps.clean workos && mix deps.get
"module WorkOS.UserManagement is not available"
- The SDK API may use different module paths — re-read the README
- Check if the SDK uses
WorkOS.SSOor another module instead
"undefined function" in controller
- Verify
use {AppName}Web, :controlleris correct - Check that the SDK functions match the README exactly
Route conflicts
- Check existing routes in router.ex for
/authprefix conflicts - Adjust the scope path if needed (e.g.,
/workos-auth)