# `Image.Components.Signing.Cloudinary`
[🔗](https://github.com/elixir-image/image_components/blob/v0.1.1/lib/image/components/signing/cloudinary.ex#L1)

Cloudinary-flavoured client-side URL signing.

Wire-format-compatible with `Image.Plug.Provider.Cloudinary.Signing`
on the server side and with Cloudinary's hosted signed URLs.
Sign-only — verification happens at the back-end.

SHA-256 over `<transforms>/<source><api-secret>`. Signature is
inserted as a path segment `s--<base64url-truncated-32>--`
between the delivery type (`upload`) and the first transform
stage.

# `sign`

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

Signs a Cloudinary path with the first key in `keys`.

### Arguments

* `path` is the path of a Cloudinary URL **without** an
  `s--<sig>--` segment.

* `keys` is a non-empty list of API secrets.

### Options

* `:expires_at` — currently unused. Cloudinary's signed-URL flow
  relies on path-bound signatures rather than a per-URL expiry
  parameter; key rotation handles long-term revocation.

### Returns

* The path with `s--<sig>--/` inserted between the delivery type
  and the transforms.

### Examples

    iex> Image.Components.Signing.Cloudinary.sign(
    ...>   "/demo/image/upload/w_200/cat.jpg",
    ...>   ["api_secret"]
    ...> )
    ...> |> String.contains?("/s--")
    true

---

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