# `PhoenixKit.Integrations.KeyStore.File`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v2.16.0/lib/phoenix_kit/integrations/key_store/file.ex#L1)

Default `PhoenixKit.Integrations.KeyStore`: one file, mode `0600`, outside
the repository.

Chosen because it works for *every* PhoenixKit user. A cloud secrets manager
is a better vault and a worse default — it needs an account, credentials and
a network, none of which a person running PhoenixKit on a single box has any
reason to own. Hosts that do have one implement the behaviour themselves.

## Where the file goes

In precedence order:

  1. `:path` in the store options;
  2. `PHOENIX_KIT_INTEGRATIONS_KEY_FILE`;
  3. `~/.config/phoenix_kit/<app>-integrations.key`, where `<app>` is the
     host application — so two sites sharing a machine get separate keys
     rather than silently sharing one.

## Refusing to write inside a repository

A path inside a git working tree is rejected outright. The whole failure this
guards against is a secret reaching a repository, and "the operator will
remember to gitignore it" is not a guarantee — a secret committed once is
compromised even after it is deleted, because history keeps it. Outside a
repository (a release directory, `/etc`, a home directory) the check does not
apply and does not get in the way.

## Permissions

Written `0600` in a directory created `0700`. On read, wider permissions are
reported through `Logger.warning` — but the secret is still returned: refusing
to decrypt would take a running application down over a permission bit, which
is a worse outcome than a loud warning. The warning names the path and the
mode, never the contents.

# `path`

```elixir
@spec path(keyword()) :: String.t()
```

The resolved path, for tests and operator-facing messages.

---

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