---
title: "Secure Phoenix APIs with API Key Authentication"
description: "Secure your Phoenix API using a shared secret."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/elixir/phoenix/secure-header"
framework: "Phoenix"
language: "Elixir"
authStrategy: "shared secret header"
pageType: use-case
---

# Secure Phoenix APIs with API Key Authentication

Secure your Phoenix API using a shared secret.

## How Zuplo Handles It

Put Zuplo in front of your Phoenix backend to authenticate API keys and forward a shared secret header so your origin only accepts traffic from Zuplo.

## Phoenix Backend Code

```elixir
defmodule MyAppWeb.Plugs.ValidateSharedSecret do
  import Plug.Conn
  require Logger

  def init(options), do: options

  def call(conn, _opts) do
    case System.get_env("SHARED_SECRET") do
      nil ->
        conn
        |> send_resp(500, "Server configuration error")
        |> halt()

      expected_secret ->
        case get_req_header(conn, "x-shared-secret") do
          [] ->
            conn
            |> send_resp(401, "No secret provided")
            |> halt()

          [secret] ->
            if valid_secret?(secret, expected_secret) do
              conn
            else
              conn
              |> send_resp(401, "Invalid secret")
              |> halt()
            end
        end
    end
  end

  defp valid_secret?(secret, expected_secret) do
    Plug.Crypto.secure_compare(secret, expected_secret)
  end
end

# Example usage in a Phoenix Router

defmodule MyAppWeb.Router do
  use MyAppWeb, :router

  pipeline :protected do
    plug MyAppWeb.Plugs.ValidateSharedSecret
  end

  scope "/api", MyAppWeb do
    pipe_through :protected

    get "/protected", ProtectedController, :index
  end
end

defmodule MyAppWeb.ProtectedController do
  use MyAppWeb, :controller

  def index(conn, _params) do
    json(conn, %{message: "Access granted"})
  end
end
```

## Example Request

```bash
curl -X GET \
  'https://your-api.zuplo.dev/your-route' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## Learn More

- [API Key Authentication on Zuplo](https://zuplo.com/docs/policies/api-key-auth-inbound)
- [JWT Authentication on Zuplo](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
- [All use cases](https://zuplo.com/use-cases)
