Attached.Web.Signer (Attached v0.2.0)

Copy Markdown View Source

Signs and verifies storage keys for secure URL generation.

A signed token encodes the storage key, an expiry timestamp, and a purpose, protected by an HMAC-SHA256 computed over the configured secret_key_base. The Plug verifies the token before serving (or accepting) any file.

The purpose binds a token to one operation: a "get" token (the default, used for serving) is rejected by the direct-upload PUT endpoint and vice versa, so a leaked download URL can never be used to overwrite a file.

Configuration

config :attached,
  secret_key_base: "your-64-byte-secret",
  url_expires_in: 300   # seconds, default 5 minutes

When secret_key_base is not configured, sign/2 only Base64url-encodes the key and verify/2 decodes without signature, expiry, or purpose checks — suitable for development and tests only.

Token format

Base64url(key|expiry|purpose).Base64url(hmac)

where hmac = HMAC-SHA256(secret, "key|expiry|purpose").

Summary

Functions

Signs key and returns a URL-safe token.

Verifies a signed token and returns {:ok, key} or {:error, reason}.

Functions

sign(key, opts \\ [])

Signs key and returns a URL-safe token.

Options:

  • :expires_in — lifetime in seconds; falls back to the configured url_expires_in, or 300 if neither is set.
  • :purpose — operation this token is valid for (default "get"). verify/2 only accepts the token for the same purpose.

When no secret_key_base is configured the key is Base64url-encoded without HMAC, expiry, or purpose.

verify(token, opts \\ [])

Verifies a signed token and returns {:ok, key} or {:error, reason}.

Accepts the same :purpose option as sign/2 (default "get") — a token signed for a different purpose fails verification.

When no secret_key_base is configured the token is decoded from Base64url and returned without signature, expiry, or purpose verification.