What is TeslaMate.Vault Used For? Transparent Encryption of Tesla API Tokens
TeslaMate.Vault provides transparent encryption of sensitive Tesla API tokens at rest using AES-256-GCM, automatically decrypting them when accessed through Ecto schemas.
TeslaMate.Vault is a critical security component in the teslamate-org/teslamate Elixir application that secures authentication credentials using the Cloak encryption library. Built as a Cloak.Vault, it ensures that access and refresh tokens remain encrypted in the database while remaining seamlessly accessible to the application during runtime. Understanding how TeslaMate.Vault handles key management and cryptographic operations is essential for properly securing self-hosted TeslaMate instances.
How TeslaMate.Vault Secures API Tokens
In lib/teslamate/vault.ex, the module defines a Cloak vault using use Cloak.Vault. This establishes the cryptographic foundation that automatically encrypts data before it reaches the database and decrypts it upon retrieval.
Key Management and Initialization
When the application starts, TeslaMate.Vault searches for an encryption key in three locations: the ENCRYPTION_KEY environment variable, the temporary directory, or the import directory. If no key exists, the vault generates a random key, logs a warning, and uses it for the current session. The discovered or generated key is then hashed with SHA-256 before being supplied to the cipher configuration.
AES-256-GCM Encryption Headers
The default cipher implementation uses AES-256-GCM with a 12-byte initialization vector (IV), defined as @iv_length 12 in the source. The resulting ciphertext includes a binary header containing the key tag, IV, and authentication tag. This structure ensures both confidentiality and integrity, preventing tampering with the stored tokens.
Ecto Integration in the Tokens Schema
The vault defines the Encrypted.Binary type in lib/teslamate/auth/tokens.ex using use Cloak.Ecto.Binary, vault: TeslaMate.Vault. This type is applied to the refresh and access fields in the TeslaMate.Auth.Tokens schema, enabling automatic encryption on writes and decryption on reads without requiring manual cryptographic calls.
# Inserting a token pair – the fields are encrypted automatically
attrs = %{
access: "access-token-plain-text",
refresh: "refresh-token-plain-text"
}
%TeslaMate.Auth.Tokens{}
|> TeslaMate.Auth.Tokens.changeset(attrs)
|> TeslaMate.Repo.insert!()
# Reading a token – the values are decrypted on access
token = TeslaMate.Repo.get!(TeslaMate.Auth.Tokens, token_id)
# `token.access` and `token.refresh` are returned as the original plain-text strings
IO.puts("Access token: #{token.access}")
IO.puts("Refresh token: #{token.refresh}")
# Providing a custom encryption key via environment variable
# (run the application with ENCRYPTION_KEY set, e.g. in a Docker env file)
System.put_env("ENCRYPTION_KEY", "my-very-secure-256-bit-key")
{:ok, _pid} = TeslaMate.Vault.start_link([])
Application Supervision and Startup
TeslaMate.Vault is started as a child of the main application supervisor in lib/teslamate/application.ex. This supervision guarantees the vault is initialized before any process attempts to access encrypted fields, preventing race conditions during authentication operations. The vault must be running for the Encrypted.Binary type to function correctly.
Summary
- TeslaMate.Vault provides transparent encryption for Tesla API tokens using AES-256-GCM via the Cloak library.
- It automatically manages encryption keys via the
ENCRYPTION_KEYenvironment variable, or generates temporary keys if none is configured. - The vault integrates seamlessly with Ecto through the
Encrypted.Binarytype defined in theTeslaMate.Auth.Tokensschema. - It is started under the main application supervisor to ensure availability before any encrypted data is accessed.
Frequently Asked Questions
What happens if ENCRYPTION_KEY is not set?
If the ENCRYPTION_KEY environment variable is not present, TeslaMate.Vault searches the temporary directory and import directory for an existing key. If none is found, it generates a random key, logs a warning about the missing configuration, and uses that key for the current session only. Any data encrypted during that session becomes permanently inaccessible if the application restarts without that specific key.
How does TeslaMate.Vault integrate with Ecto?
TeslaMate.Vault defines the Encrypted.Binary type using Cloak.Ecto.Binary with the vault specified as TeslaMate.Vault. This type is used in the TeslaMate.Auth.Tokens schema for the access and refresh fields. When Ecto writes these fields to the database, Cloak automatically encrypts the values. When reading, the library transparently decrypts them back to plain text before returning them to the application code.
What encryption algorithm does TeslaMate.Vault use?
The vault uses AES-256-GCM (Galois/Counter Mode) as its default cipher. It generates a 12-byte IV for each encryption operation and produces ciphertext that includes a header containing the key tag, IV, and authentication tag. This authenticated encryption mode provides both confidentiality and integrity verification for the stored API tokens.
Where is TeslaMate.Vault started in the application?
TeslaMate.Vault is started as a child process of the main application supervisor in lib/teslamate/application.ex. This placement in the supervision tree ensures the vault is fully initialized and ready to handle cryptographic operations before any other part of the system attempts to read or write encrypted token data.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →