# `Ankusa.BlobStore.SSE`
[🔗](https://github.com/jamescarr/ankusa/blob/ankusa-v0.7.0/packages/ankusa/lib/ankusa/blob_store/sse.ex#L1)

Server-side encryption for the objects an `Ankusa.BlobStore` writes: the
`:sse` option of `Ankusa.BlobStore.S3`, `GCS`, `Azure` and `OCI`.

    sse: %{type: :aes256}
    sse: %{type: :kms, key_id: "arn:aws:kms:us-east-1:111122223333:key/…"}

It is sent on **every** `put/4` of the store it is set on: segments, backups
(`backup/…`) and claim packs alike, because they all reach the object store
through the adapter's `put/4` with that store's options. Reads and deletes
carry nothing: the provider decrypts transparently.

| Adapter | `type: :aes256` | `type: :kms` |
| --- | --- | --- |
| `S3` | `x-amz-server-side-encryption: AES256` | `x-amz-server-side-encryption: aws:kms`, plus `x-amz-server-side-encryption-aws-kms-key-id` when `key_id` is set (without it S3 uses the bucket's default KMS key) |
| `GCS` | nothing: GCS encrypts every object | `x-goog-encryption-kms-key-name`, and the `kmsKeyName` upload parameter; `key_id` is the key's resource name and is required |
| `Azure` | nothing: Blob Storage encrypts every blob | `x-ms-encryption-scope`; `key_id` is the encryption scope's name and is required |
| `OCI` | nothing: Object Storage encrypts every object | `opc-sse-kms-key-id`; `key_id` is the Vault key's OCID and is required |

`type: :aes256` on GCS, Azure and OCI is accepted and sends nothing, so one
config can say "encrypted" for every provider; only `:kms` changes the key.
The S3 headers are signed with the rest of the request. A local store
(`Ankusa.BlobStore.LocalFS`) refuses the option: its files rest on the
node's volume.

A misspelled option is a boot error (`validate!/3`), not an unencrypted
object.

# `adapter`

```elixir
@type adapter() :: :s3 | :gcs | :azure | :oci
```

# `headers`

```elixir
@spec headers(keyword(), adapter()) :: [{String.t(), String.t()}]
```

The request headers `opts[:sse]` asks `adapter` to send on a `PUT`.

# `query`

```elixir
@spec query(keyword(), adapter()) :: [{String.t(), String.t()}]
```

The query parameters `opts[:sse]` adds to a GCS upload (`kmsKeyName`).

# `validate!`

```elixir
@spec validate!(module(), term(), String.t()) :: :ok
```

Check a blob store's `:sse` option and raise `ArgumentError` naming `where`
(`"storage.blob_store"`) when it cannot do what it says. Stores without the
option, and modules this package does not know, pass.

---

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