Security Recommendations
========================

This page is the practical answer to:

**"Which Epicrypt option should I choose for a new application?"**

Quick Picks
-----------

If you are starting fresh, prefer these defaults:

- Password hashing: ``PasswordHasher`` with ``SecurityProfile::MODERN``
- Password upgrades: ``verifyAndRehash()``
- App payload encryption: ``DataProtection\StringProtector``
- Large file encryption: ``DataProtection\FileProtector``
- Envelope-style protected storage: ``DataProtection\EnvelopeProtector``
- API tokens with one shared secret: ``Token\Jwt\SymmetricJwt``
- API tokens with separate signer/verifier trust: ``Token\Jwt\AsymmetricJwt``
- Revocable random bearer tokens: ``Token\Opaque\OpaqueToken``
- Small signed action/reset payloads: ``Token\Payload\SignedPayload``
- Browser workflow tokens: ``Security`` domain helpers such as ``PasswordResetToken`` and ``SignedUrl``
- New ciphertext formats: modern ``DataProtection`` APIs

Public Surface First
--------------------

For new applications, start from these domains first:

- ``Password``
- ``Token``
- ``DataProtection``
- ``Security``

Treat these as lower-level or advanced:

- ``Crypto`` for direct primitive control

Choose the Right Tool
---------------------

Passwords
^^^^^^^^^

Use:

- ``PasswordHasher`` for stored user passwords
- ``PasswordStrength`` for quality feedback
- ``verifyAndRehash()`` when you want login-time hash upgrades

Prefer:

- ``SecurityProfile::MODERN``
- default Argon2id-based hashing

Avoid:

- custom password hashing logic
- storing app secrets as password hashes when you actually need reversible protection

Secrets and Stored Sensitive Values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Use:

- ``WrappedSecretManager`` for secrets that must be unwrapped later
- ``SecureSecretSerializer`` for structured secret-bearing data
- ``KeyRing`` plus rewrap helpers during rotation windows

Prefer:

- one active master secret
- short fallback windows for previous key versions

Protected Data
^^^^^^^^^^^^^^

Use:

- ``StringProtector`` for ordinary application payloads
- ``EnvelopeProtector`` when you want a structured encoded envelope
- ``FileProtector`` for large files and streaming-safe encryption
- ``FileProtector::reencryptWithAnyKey()`` when rotating protected files across key versions

Prefer:

- re-encrypting artifacts under the active key when fallback keys match
- ``decryptWithAnyKey()`` or ``reencryptWithAnyKey()`` only during rotation windows
- result helpers like ``decryptWithAnyKeyResult()`` when rotation code needs to know which key matched

Avoid:

- using low-level crypto primitives directly unless you really need them

Tokens
^^^^^^

Use:

- ``SymmetricJwt`` when issuer and verifier share one secret
- ``AsymmetricJwt`` when the signer should keep a private key and verifiers should only need public keys
- ``OpaqueToken`` when token contents should stay server-side
- ``SignedPayload`` for compact signed internal flows

Prefer:

- ``kid`` plus key-set mode when rotating JWT signing keys
- ``KeyRing``-based verification helpers during short transition windows
- ``verifyWithAnyKeyResult()`` when callers need to know whether a fallback key matched

Avoid:

- mixing symmetric and asymmetric expectations in one verification path
- exposing sensitive state in JWT claims when opaque tokens fit better

Crypto Primitives
^^^^^^^^^^^^^^^^^

Use:

- ``AeadCipher`` for authenticated encryption of short payloads
- ``SecretBoxCipher`` when you specifically want secretbox semantics
- ``SecretStream`` or ``FileProtector`` for large file workflows
- ``Mac`` for shared-secret integrity
- ``Signature`` for public/private signature verification

Prefer:

- ``AeadAlgorithm::XCHACHA20_POLY1305_IETF`` for new AEAD usage
- higher-level ``DataProtection`` APIs unless the primitive is truly what you need

Key Material and Derivation
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Use:

- ``KeyMaterialGenerator`` for fresh random keys
- ``KeyDeriver`` for derived keys
- purpose-aware key generation helpers when available

Prefer:

- generated keys for encryption keys
- derived keys when the design specifically needs deterministic derivation
- explicit context/info separation for derived subkeys

Key Rotation
------------

Use key-ring helpers during planned key rollover.

Prefer this pattern:

1. issue new artifacts with the active key
2. keep decode/verify paths able to read active and fallback keys during rollout
3. re-encrypt or re-issue under the active key when a fallback key matches
4. remove fallback keys after the rollover window closes

In particular:

- prefer ``StringProtector`` and ``EnvelopeProtector`` for new protected data
- follow the key rotation cookbook for active-key and fallback-key rollout patterns

Binary vs Base64URL
-------------------

Most public Epicrypt APIs expect Base64URL strings by default.

Use explicit context flags only when you are intentionally passing raw binary values, for example:

- ``key_is_binary``
- ``nonce_is_binary``
- ``salt_is_binary``

When possible, keep one format per application boundary instead of mixing both styles in the same layer.

Simple Rule of Thumb
--------------------

- If a higher-level ``Password``, ``Security``, ``Token`` or ``DataProtection`` API fits your use case, choose it first.
- Reach for ``Crypto`` primitives only when you need direct cryptographic control.
- Prefer modern defaults and active-key rotation.
