💃 Tango

Hex.pm Hex Docs License

OAuth integrations for Phoenix — sessions, encrypted tokens, and multi-tenant connections.

Tango is an Elixir library for third-party OAuth in Phoenix apps. It is compatible with Nango's provider catalog and stores tokens encrypted in Postgres via your host Ecto repo.

Why Tango?

Prerequisites

Installation

Add tango to your dependencies in mix.exs:

def deps do
  [
    {:tango, "~> 0.4.1"}
  ]
end

Then fetch dependencies:

mix deps.get

Quick Start

1. Configure

# config/config.exs
config :tango,
  repo: MyApp.Repo,
  encryption_key: System.get_env("TANGO_ENCRYPTION_KEY"),
  api_key: System.get_env("TANGO_API_KEY")

Generate an encryption key:

openssl rand -base64 32

2. Install the schema

mix tango.setup writes a host-owned wrapper migration; mix ecto.migrate applies it. Use setup for the initial install only — upgrades need a separate pinned migration (see SETUP.md).

mix tango.setup
mix ecto.migrate

3. Create a provider

mix tango.providers.create github \
  --client-id=your_client_id \
  --client-secret=your_client_secret

4. Run a direct OAuth flow

tenant_id = "user-123"
redirect_uri = "https://yourapp.com/auth/callback"

{:ok, session} =
  Tango.create_session("github", tenant_id,
    redirect_uri: redirect_uri,
    scopes: ["user:email", "repo"]
  )

{:ok, auth_url} =
  Tango.authorize_url(session.session_token, redirect_uri: redirect_uri)

# Redirect the user to auth_url. After the provider returns state + code:

{:ok, connection} =
  Tango.exchange_code(state, code, tenant_id, redirect_uri: redirect_uri)

{:ok, connection} = Tango.get_connection_for_provider("github", tenant_id)
headers = [{"Authorization", "Bearer #{connection.access_token}"}]

The direct server-side flow above stores a credential connection. For browser popups, staged connection completion is the default: verify the account on your server, then finalize a credential connection together with your host writes.

For a point-in-time account link or organization administrator check, opt into completion_mode: :consume when creating an authorization session. After server verification, Tango.Authorization.multi_consume_authorization/5 commits a safe identity proof with your host writes and erases the staged credentials without creating a connection. See AUTHORIZATION.md for both lifecycles and host-owned examples. Consume mode supports neither refreshed credentials nor background imports.

Nango catalog compatibility covers provider configuration and OAuth transport. Tango makes credential retention an explicit host-selected policy; this verify-and-consume API is a Tango extension with no documented Nango consume API equivalent. Local credential erasure does not revoke the provider's authorization.

Documentation

Testing

Requires local PostgreSQL with postgres:postgres credentials. Consumer tests can insert providers and connections with Tango.Testing.

mix test
mix coveralls
mix quality

License

See LICENSE.