Správa kľúčov
Kľúče žijú v pomenovaných kruhoch: default pre pečate, denník a kontrolné body; http pre podpisy správ; a vaše vlastné — napríklad kruh financial so silnejšími kľúčmi, ktorý pečať zvolí cez ring(). Id kľúča sa hľadá len v jeho kruhu a algoritmus vždy určuje kľúč — nikdy uložený riadok ani prijatý parameter.
| Driver | Odkiaľ sú kľúče | Rotácia |
|---|---|---|
| config (kruh default) | SENTINEL_KEY_ID / SENTINEL_KEY (+ SENTINEL_PREVIOUS_KEYS pre kľúče len na overovanie) | sentinel:key:rotate vypíše nové riadky env |
| database (kruh http) | Riadky sentinel_keys: AES-256-GCM pod kľúčom odvodeným z APP_KEY len pre obálky (nikdy nie aplikačný encrypter), každé pole viazané — upravený, skopírovaný či podstrčený riadok sa odmietne | sentinel:key:rotate uloží nový kľúč; starý je potom len na overovanie |
chain | Drivery v poradí (vyhráva prvý podpisový kľúč) | podľa drivera |
Algoritmy a materiál
| Algoritmus | Materiál | Pečate | HTTP |
|---|---|---|---|
hmac-sha256 | Koreňové tajomstvo 32–1024 bajtov; HKDF podkľúče 32 bajtov | áno | áno (surové zdieľané tajomstvo) |
hmac-sha384 | Koreň ≥ 32 bajtov; podkľúče 48 bajtov | áno | — |
hmac-sha512 | Koreň ≥ 32 bajtov; podkľúče 64 bajtov | áno | — |
ed25519 | 64-bajtový tajný kľúč libsodium / 32-bajtový verejný kľúč | áno | áno |
ecdsa-p256-sha256 | PKCS#8 / SPKI PEM, P-256 | áno | áno |
ecdsa-p384-sha384 | PKCS#8 / SPKI PEM, P-384 | áno | áno |
Materiál je vždy v tvare base64:<štandardné base64> — holý reťazec sa odmietne, čo blokuje heslá. Koreň HMAC má 32–1024 náhodných bajtov (nikdy PEM, nikdy jeden opakovaný bajt); Ed25519 je 64-bajtový tajný kľúč a/alebo 32-bajtový verejný kľúč; ECDSA je base64 textu PEM s krivkou overenou voči algoritmu. Materiál sa nikdy neobjaví vo výnimkách, logoch, udalostiach, about, var_dump() ani v serializovaných dátach.
API
use RoundlyConsulting\Sentinel\Enums\Algorithm;
use RoundlyConsulting\Sentinel\Enums\KeyDestination;
Sentinel::keys()->rings(); // ['default', 'http']
Sentinel::keys()->all(); // KeyInfo of every key in every ring — never material
Sentinel::keys()->ring()->current(); // KeyInfo of the default ring's signing key
$ring = Sentinel::keys()->ring('http'); // KeyRingHandle; a kid of another ring is unknown here
$ring->name(); // 'http'
$ring->find('acme-2026-10'); // ?KeyInfo
$ring->all();
$ring->generate(Algorithm::Ed25519, keyId: 'acme-2026-11', activatesAt: now()->addWeek()); // stored, pending until then
$ring->import('acme-2026-10', Algorithm::EcdsaP256Sha256, $pem, owner: $partner);
$ring->rotate(); // RotationResult: current, previous (now verify-only)
$ring->revoke('acme-2026-10', reason: 'Partner offboarded', actor: $admin);
$ring->retire('acme-2025-10');
$lines = Sentinel::keys()->ring()->generate(Algorithm::HmacSha256, destination: KeyDestination::Config)->envSnippet;- Predvolené hodnoty sa líšia zámerne. generate() uloží kľúč do databázového úložiska kruhu (KeyDestination::Database; kruh bez neho vyhodí KeyDriverException::readOnly), kým KeyDestination::Config vráti riadky env v envSnippet a nič neuloží. sentinel:key:generate robí opak: riadky env, pokiaľ nezadáte --database.
- rotate() rotuje v úložisku, kde žije aktuálny podpisový kľúč; signs_until predošlého kľúča sa nastaví na aktiváciu nového, takže sa prekrývajú bez medzery.
- revoke() a retire() menia len kľúče v databáze. Kľúč z konfigurácie vyhodí KeyDriverException::notStoredInDatabase: odvoláte ho pridaním ring:kid do SENTINEL_REVOKED_KEYS a vyradíte odstránením zo zoznamu kľúčov kruhu len na overovanie — sentinel:key:revoke a sentinel:key:retire namiesto chyby vypíšu presne tento postup.
- Dôvod odvolania je povinný (1–1 000 znakov); retire() ukončí obdobie overovania kľúča okamžite, takže pečate, ktoré ho stále používajú, hlásia RetiredKey.
use RoundlyConsulting\Sentinel\DataTransferObjects\GenerateKeyRequest;
use RoundlyConsulting\Sentinel\DataTransferObjects\RevokeKeyRequest;
use RoundlyConsulting\Sentinel\DataTransferObjects\RotateKeyRequest;
$key = Sentinel::generateKey(new GenerateKeyRequest('http', Algorithm::Ed25519, keyId: 'acme-2027-01', owner: $partner));
$rotation = Sentinel::rotateKey(new RotateKeyRequest('http'));
Sentinel::revokeKey(new RevokeKeyRequest('http', 'acme-2027-01', 'Partner offboarded', $admin));
Sentinel::retireKey('http', 'acme-2025-10');
Sentinel::listKeys('http'); // null = every ring
Sentinel::findKey('http', 'acme-2027-01'); // ?KeyInfo
Sentinel::currentKey(); // null = keys.default_ringStavy
Stavy zodpovedajú NIST SP 800-57 — pending → active → verify-only → retired, plus revoked — a efektívny stav sa určuje v tomto poradí:
| Stav | Kedy | Podpisuje | Overuje |
|---|---|---|---|
Revoked | ring:kid v keys.revoked (vždy vyhráva), alebo odvolaný | nie | nie |
Retired | uplynulo verifies_until, alebo vyradený | nie | nie (dôkazy v denníku sa stále overia) |
Pending | activates_at v budúcnosti | nie | nie |
VerifyOnly | uplynulo signs_until, kľúč previous v konfigurácii, alebo len verejný materiál | nie | áno |
Active | inak | áno (so súkromným/tajným materiálom) | áno |
SENTINEL_REVOKED_KEYS (ring:kid,…) odvolá kľúč bez ohľadu na to, čo hovorí jeho driver — obnovený riadok v databáze odvolanie nikdy nezruší.
Import kľúčov
Pridajte partnera za behu — bez nasadenia, s kľúčom viazaným na model partnera:
$ring->import('acme-2026-10', Algorithm::Ed25519, $publicKeyPemOrBase64, owner: $partner, label: 'ACME');
Sentinel::importKey(new ImportKeyRequest('http', 'acme-2026-10', Algorithm::Ed25519, $pem, owner: $partner));php artisan sentinel:key:import acme-2026-10 --ring=http --algorithm=ed25519 --file=acme.pem \
--owner-type=partner --owner-id=7import() uloží existujúci materiál do databázového úložiska kruhu: verejný kľúč partnera (Ed25519 surový alebo SPKI PEM, ECDSA PEM) alebo dohodnuté tajomstvo HMAC, viazaný na model vlastníka a len na overovanie — nikdy nepodpisuje, ani ako aktuálny kľúč kruhu, ani cez Http::withSignature() — pokiaľ nie je importovaný so signing: true (vlastný pár kľúčov presúvaný z prostredia do databázy; bez toho sa súkromný materiál odmietne). Stav je viazaný v zašifrovanej obálke, kid musí byť voľný v celom kruhu a odošle sa KeyImported.
Rotácia
- Databázový kruh: rotate() vytvorí nový aktívny kľúč (voliteľne s neskoršou aktiváciou cez activatesAt); predošlý kľúč je po aktivácii nového len na overovanie. Staré pečate ostanú Intact, nové používajú nový kid.
- Kruh z konfigurácie: sentinel:key:rotate vypíše nové SENTINEL_KEY_ID / SENTINEL_KEY a aktualizované SENTINEL_PREVIOUS_KEYS so starým kľúčom len na overovanie.
- Potom presuňte staré pečate na nový kľúč cez sentinel:reseal — nikdy potichu nelegalizuje zmenu a --from-key= ho obmedzí na jeden starý kid.
- Kľúč vyraďte, keď ho už nič nepoužíva (sentinel:key:retire odmietne, kým ho pečate na ktoromkoľvek pripojení denníka používajú, pokiaľ nezadáte --force); kompromitovaný kľúč okamžite odvolajte.
Drivery config a database
Driver config drží kľúče mimo databázy — odporúčané nastavenie pre pečate:
SENTINEL_KEY_ID=default-20261002-k3f9qa
SENTINEL_ALGORITHM=hmac-sha256
SENTINEL_KEY="base64:…"
SENTINEL_PUBLIC_KEY="base64:…" # asymmetric keys; alone = verify-only
SENTINEL_PREVIOUS_KEYS="default-20250901-a1b2c3|hmac-sha256|base64:…" # verify-only, comma-separatedDriver database ukladá riadky sentinel_keys, ktorých autoritatívna obálka je AES-256-GCM pod kľúčom odvodeným z APP_KEY len pre obálky (s podporou rotácie cez APP_PREVIOUS_KEYS). Viaže každé pole — kruh, kid, algoritmus, materiál, verejný kľúč, stav, dátumy, vlastníka — takže riadok, ktorého nešifrované stĺpce nesúhlasia s obálkou, vyvolá KeyIntegrityException, spustí KeyIntegrityViolated a považuje sa za neznámy. Kľúče v databáze sú len také bezpečné ako APP_KEY, preto pre predvolený kruh uprednostnite driver config. chain číta svoje drivery v poradí — vyhráva prvý podpisový kľúč.
Uzly len na overovanie
Servery, ktoré majú overovať, no nikdy nepečatiť, nakonfigurujú len verejnú polovicu (SENTINEL_KEY_ID, SENTINEL_ALGORITHM, SENTINEL_PUBLIC_KEY, bez SENTINEL_KEY) a SENTINEL_AUTO_SEAL=false. Overia všetko; explicitné seal() vyhodí NoSigningKeyException.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.