# `Rho.CredentialStore`
[🔗](https://github.com/GenericJam/rho/blob/v0.1.0/lib/rho/credential_store.ex#L1)

Where rho keeps secrets: the provider sign-ins and API keys
(`Rho.Auth`), a binary value per string key. A host seam:
`config :rho, :credential_store, Module` picks the backend.

The default, `Rho.CredentialStore.File`, keeps each key in a 0600 file
under `<data dir>/secure/`: right for a computer and for tests. A phone
app plugs in the platform's secure store (Android Keystore / iOS
Keychain); the mob_secure_store plugin's `MobSecureStore` has exactly
this shape and can be configured as it is. A store that can't work on
this device (its native code missing) should fail closed, answering
every call `{:error, :secure_store_unavailable}`, rather than fall back
to plain files: `Rho.Auth` then reports it instead of signing in.

Keys are non-empty UTF-8 strings; values arbitrary binaries (rho stores
JSON).

# `delete`

```elixir
@callback delete(key :: String.t()) :: :ok | {:error, term()}
```

Removes `key`; removing an absent one is `:ok`.

# `get`

```elixir
@callback get(key :: String.t()) :: {:ok, binary()} | :error | {:error, term()}
```

The value at `key`: `{:ok, value}`, `:error` when there is none, `{:error, reason}` when the store failed.

# `put`

```elixir
@callback put(key :: String.t(), value :: binary()) :: :ok | {:error, term()}
```

Upserts `key`, durably (`:ok` means written, not queued).

# `backend`

```elixir
@spec backend() :: module()
```

The backend in effect (`Rho.Config.credential_store/0`).

# `delete`

```elixir
@spec delete(String.t()) :: :ok | {:error, term()}
```

The configured backend's `c:delete/1`.

# `get`

```elixir
@spec get(String.t()) :: {:ok, binary()} | :error | {:error, term()}
```

The configured backend's `c:get/1` (`backend/0`); a host may keep its own secrets here too.

# `put`

```elixir
@spec put(String.t(), binary()) :: :ok | {:error, term()}
```

The configured backend's `c:put/2`.

---

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