Skip to content

Commit

Permalink
Merge pull request #2 from venndr/docs/readme
Browse files Browse the repository at this point in the history
docs: massage readme
  • Loading branch information
nikcorg authored Feb 8, 2022
2 parents 477a7e4 + d1db1a3 commit 32bfbf2
Showing 1 changed file with 51 additions and 57 deletions.
108 changes: 51 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ end

## Usage

To use Erebus you need to wrap it and provide your backend configuration. Include a module like the example below in your app:
To use Erebus you need to wrap it to provide your backend configuration. Create a module like the example below in your app:

```elixir
defmodule MyApp.Erebus do
Expand All @@ -47,14 +47,6 @@ defmodule MyApp.Erebus do
end
```

For the encryptable fields implement the `Erebus.Encryption` protocol:

```elixir
defimpl Erebus.Encryption do
def encrypted_fields(_), do: [:first, :second]
end
```

In an encrypted struct, Erebus requires several fields for each encrypted property. Follow the
example below to define your structs:

Expand All @@ -71,9 +63,9 @@ defmodule SecureModel
# this field contains the ciphertext for the `second` field
second_encrypted: binary(),

# this field contains a hashed version of the `first` field
# this field contains a hashed version of the unencrypted `first` field
first_hash: String.t(),
# this field contains a hashed version of the `second` field
# this field contains a hashed version of the unencrypted `second` field
second_hash: String.t(),

# this field contains the DEK (data encryption key)
Expand All @@ -82,9 +74,9 @@ defmodule SecureModel
end
```

In this example `first` and `second` are the names of the encryptable fields. The unsuffixed fields are virtual, meaning they are only used for encrypting or populated after decrypting the `*_encrypted` equivalent fields – they are not read from or written to the database. The `dek` field contains the DEK.
In this example `first` and `second` are the names of the encryptable fields. The _unsuffixed_ fields are virtual, meaning they are only used for encrypting (before write), or are populated after decrypting the equivalent `*_encrypted` fields – only _suffixed_ fields are written to the database. The `dek` field contains the DEK.

The `*_hash` suffixed fields are hashed (using SHA512) versions of the plain text field content. They are useful in queries for looking up exact matches without decrypting the content.
The `*_hash` suffixed fields are hashed (using SHA512) versions of the plain text field content. They can be used for finding exact matches without having to decrypt the content.

When using [Ecto](https://hex.pm/packages/ecto), fields are defined using the `hashed_encrypted_field(:field_name)` and `data_encryption_key()` macros, which create all the necessary auxiliary fields for you:

Expand All @@ -98,60 +90,62 @@ embedded_schema "table" do
end
```

### Usage with local KMS adapter

Provide the following values in config:

```elixir
config :my_app, :erebus,
kms_backend: Erebus.KMS.Local,
keys_base_path: "some_path",
private_key_password: "1234"
```

And generate asymmetric key pairs (named `public.pem` and `private.pem`) in the folder at `keys_base_path`.

### Usage with Google KMS adapter

Please include [Goth](https://hex.pm/packages/goth) in your application:
Additionally you must implement the `Erebus.Encryption` protocol to mark the fields which should be encrypted:

```elixir
{:goth, "~> 1.3.0-rc.2"}
defimpl Erebus.Encryption do
def encrypted_fields(_), do: [:first, :second]
end
```

and start it in your application.ex:

```elixir
credentials =
"GCP_KMS_CREDENTIALS_PATH"
|> System.fetch_env!()
|> File.read!()
|> Jason.decode!()

scopes = ["https://www.googleapis.com/auth/cloudkms"]

source = {:service_account, credentials, scopes: scopes}
### Usage with local KMS adapter

children = [
{Goth, name: MyApp.Goth, source: source}
]
```
1. Set the following values in your application config:
```elixir
config :my_app, :erebus,
kms_backend: Erebus.KMS.Local,
keys_base_path: "path_to_directory_containing_a_key_pair",
private_key_password: "1234"
```
2. Generate asymmetric key pairs (named `public.pem` and `private.pem`) in the folder at `keys_base_path`.

and provide `name` as one of the options to Erebus:
### Usage with Google KMS adapter

```elixir
config :my_app, :erebus,
kms_backend: Erebus.KMS.Google,
google_project: "someproject",
google_region: "someregion",
google_keyring: "some_keyring",
google_goth: MyApp.Goth
```
1. Include [Goth](https://hex.pm/packages/goth) in your application:
```elixir
{:goth, "~> 1.3.0-rc.2"}
```
2. Start Goth in your `application.ex`:
```elixir
credentials =
"GCP_KMS_CREDENTIALS_PATH"
|> System.fetch_env!()
|> File.read!()
|> Jason.decode!()

scopes = ["https://www.googleapis.com/auth/cloudkms"]

source = {:service_account, credentials, scopes: scopes}

children = [
{Goth, name: MyApp.Goth, source: source}
]
```
3. Pass the app's `name` in the `google_goth` option to Erebus:
```elixir
config :my_app, :erebus,
kms_backend: Erebus.KMS.Google,
google_project: "someproject",
google_region: "someregion",
google_keyring: "some_keyring",
google_goth: MyApp.Goth
```
Please note that if you're using Google KMS, your key must have access to the following roles:

- Cloud KMS CryptoKey Encrypter/Decrypter
- Cloud KMS CryptoKey Public Key Viewer
- [Cloud KMS CryptoKey Encrypter](https://cloud.google.com/kms/docs/reference/permissions-and-roles#cloudkms.cryptoKeyEncrypter)
- [Cloud KMS CryptoKey Decrypter](https://cloud.google.com/kms/docs/reference/permissions-and-roles#cloudkms.cryptoKeyDecrypter)
- [Cloud KMS CryptoKey Public Key Viewer](https://cloud.google.com/kms/docs/reference/permissions-and-roles#cloudkms.publicKeyViewer)

### Ecto usage full example

Expand Down

0 comments on commit 32bfbf2

Please sign in to comment.