# AuthPlugIntroduct
A secure Elixir Plug for authenticating requests using RSA public key cryptography. Clients sign requests with their private key; AuthPlugIntroduct verifies the signature using the stored public key.
## Installation
Add to your `mix.exs` deps:
```elixir
def deps do
[
{:auth_plug_introduct, "~> 0.1.0"}
]
end
```
## Configuration
In `config/config.exs`:
```elixir
config :auth_plug_introduct,
key_header: "key_id", # Header with user UUID
sign_header: "sign", # Header with Base64-encoded signature
repo: YourApp.Repo,
user_schema: YourApp.User
```
## User Schema
Your User schema must have:
```elixir
schema "users" do
field :uuid, :binary_id, primary_key: true
field :pub_key, :string # RSA public key in PEM format
end
```
## Usage
Add to your Phoenix router:
```elixir
pipeline :api_auth do
plug AuthPlugIntroduct.AuthUser
end
scope "/api", YourAppWeb do
pipe_through :api_auth
get "/profile", ProfileController, :show
post "/items", ItemController, :create
end
```
Access the authenticated user:
```elixir
defmodule YourAppWeb.ProfileController do
def show(conn, _params) do
user = conn.assigns[:current_user]
json(conn, %{uuid: user.uuid, email: user.email})
end
end
```
## How It Works
1. Client includes headers: `key_id` (user UUID) and `sign` (Base64-encoded RSA signature)
2. AuthPlugIntroduct extracts headers and loads user from database
3. Verifies the signature against the request body using the user's public key
4. On success: user assigned to `conn.assigns[:current_user]`
5. On failure: returns 401 (missing/invalid headers) or 403 (signature invalid)
## Key Generation
Generate RSA key pair:
```bash
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
```
Store the public key in your database:
```elixir
public_key_pem = File.read!("public_key.pem")
YourApp.Repo.insert!(%YourApp.User{
uuid: Ecto.UUID.generate(),
email: "user@example.com",
pub_key: public_key_pem,
active: true
})
```
## Error Responses
**401 Unauthorized**
- Missing `key_id` or `sign` header
- User UUID not found in database
- Invalid Base64-encoded signature
**403 Forbidden**
- Signature verification failed
- Request body was modified after signing
- User's public key is invalid
## Security Notes
- Always use HTTPS/TLS for all requests
- Currently uses SHA-1; consider upgrading to SHA-256 for production
- Never commit private keys to version control
- Implement rate limiting to prevent brute force attacks
- Consider checking `user.active` field before granting access
- Request body is read entirely into memory; set appropriate size limits
## Troubleshooting
**401 errors**: Verify headers match configuration names, check user exists in database
**403 errors**: Ensure request body matches exactly what was signed, verify key pair is valid
**PEM format errors**: Ensure public key starts with `-----BEGIN PUBLIC KEY-----` and has no extra whitespace