# Encryption

> How ShopAssist encrypts data in transit and at rest, including the envelope encryption of credentials and AI keys.

Source: https://shopassist.coec.dk/docs/security/encryption · Updated 2026-10-01

## In transit [#in-transit]

Every endpoint uses TLS 1.2 or newer with HSTS. Calls to your store, AI providers, helpdesks and webhook endpoints use HTTPS with certificate validation and never follow redirects to non-HTTPS URLs.

## At rest [#at-rest]

Servers and backups use disk encryption. On top of that, secrets are encrypted in the application before they reach the database:

* store connection credentials and plugin secrets;
* your AI provider keys (BYOK);
* helpdesk tokens, Slack webhook URLs and webhook signing secrets;
* two-factor authentication secrets.

Each value gets its own random 256-bit key (AES-256-GCM), which is itself encrypted with a master key that only the services that need it hold. Every encrypted value is bound to its table, row and tenant, so a value copied to another row or store cannot be decrypted. Master keys are rotated at least every 12 months.

## Secrets shown once [#shown-once]

API keys, webhook secrets, identity secrets and status-webhook URLs are shown once when created. ShopAssist stores only a hash of API keys and never returns stored credentials, not even to owners. To change one, rotate it.

## Passwords [#passwords]

Passwords are hashed with Argon2id. New passwords are checked against known breached passwords. Accounts lock for 15 minutes after repeated failed sign-ins.
