# `Image.Plug.Provider.ImageKit.Signing`
[🔗](https://github.com/elixir-image/image_plug/blob/v0.1.0/lib/image/plug/provider/image_kit/signing.ex#L1)

ImageKit-flavoured HMAC URL signing.

Per [ImageKit's docs](https://imagekit.io/docs/security#how-to-create-signed-urls):

* HMAC-SHA1 over the canonical-string `<path-without-host><expiry-or-empty>`
  where `<path-without-host>` is the request path-and-query
  **excluding** the `ik-s` parameter and `<expiry-or-empty>` is
  the value of the `ik-t` parameter (or empty when absent).

* Hex digest, lowercase.

* Parameters: appended as `ik-s=<hex>` and optionally
  `ik-t=<unix-seconds>`.

v0.1 ships HMAC-SHA1 (matching ImageKit's documented default).

# `sign`

```elixir
@spec sign(String.t(), [String.t(), ...], keyword()) :: String.t()
```

Signs `path_with_query` (a request path, optionally with a query
string) using the first key in `keys`. Returns the path with
`?ik-s=<hex>` (or `&ik-s=<hex>` if a query is already present)
appended.

### Options

* `:expires_at` — `DateTime` or unix-seconds. Adds an
  `ik-t=<unix>` parameter; the verifier rejects after that time.

# `verify`

```elixir
@spec verify(String.t(), [String.t(), ...], keyword()) ::
  :ok | {:error, Image.Plug.Error.t()}
```

Verifies the signature on `path_with_query`.

Returns `:ok` or an `Image.Plug.Error` with one of
`:signature_required`, `:invalid_signature`, `:signature_expired`.

### Options

* `:required?` — when `true`, missing `?ik-s=` produces
  `:signature_required`. Default `false`.

* `:now` — current unix-seconds for expiry comparison.
  Defaults to `System.system_time(:second)`. Test-only override.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
