NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky

Každý bod rozšírenia je kontrakt v RoundlyConsulting\Sentinel\Contracts, ktorý sa získava z kontajnera — Sentinel::fake() aj prepisy v aplikácii teda fungujú ďalej. Drivery registrujte v metóde boot() service providera:

use Illuminate\Contracts\Container\Container;
use RoundlyConsulting\Sentinel\Contracts\Anchor;
use RoundlyConsulting\Sentinel\Contracts\KeyStore;

// A key-store driver (e.g. a KMS): name it in keys.rings.<ring>.driver.
Sentinel::extend('vault', fn (Container $app, string $ring, array $config): KeyStore => new VaultKeyStore($ring, $config));

// An anchor: name it in SENTINEL_ANCHORS.
Sentinel::extendAnchor('s3-lock', fn (Container $app, array $config): Anchor => new ObjectLockAnchor($config));
KontraktMetódyPredvolené / napojenie
Contracts\KeyStoresigningKey(): SealingKey, find(string $keyId): ?SealingKey, all(): list<KeyInfo>, supportsWrites(): boolconfig, database, chain; vlastný cez Sentinel::extend()
Contracts\Anchorname(): string, publish(AnchorPayload $payload): void, latest(string $connection): ?AnchorPayloadcache, filesystem, log; vlastná cez Sentinel::extendAnchor() (latest() null = len zápis)
Contracts\IdempotencyStorebegin(), complete(), release(), forget(), prune()podľa idempotency.store
Contracts\NonceStoreissue(), consume(), remember(), prune()podľa nonces.store
Contracts\IdempotencyScopeResolverresolve(Request $request): stringIdempotency\RequestScope (používateľ, inak kľúč podpisu, inak IP)
Contracts\AcknowledgementPolicyauthorize(AcknowledgeRequest $request): ?stringGate kontrola acknowledgement.ability (null = povolené, inak kód zamietnutia)
Contracts\SealDefinitiondefine(SealDefinitionBuilder $seal): void->using(MyDefinition::class)
Contracts\Sealablestatic defineSeals(SealBuilder $seals): voidvaše modely s HasSeals

Úložiská kľúčov (KMS, Vault, HSM)

// config/sentinel.php
'keys' => ['rings' => ['financial' => ['driver' => 'vault', 'algorithms' => ['ed25519']]]],

interface KeyStore
{
    public function signingKey(): SealingKey;          // NoSigningKeyException when none
    public function find(string $keyId): ?SealingKey;  // any status; null when unknown
    /** @return list<KeyInfo> */
    public function all(): array;
    public function supportsWrites(): bool;            // false: generate/rotate print env lines
}

Kľúče zostavujte cez verejné rozhranie na rozšírenie. KeyMaterial overí materiál presne tak ako vstavané drivery a drží ho mimo výpisov aj serializácie (fromEncoded(), generate(), canSign(), encodedPrivate(), encodedPublic()); vracajte inštancie SealingKey s ich efektívnym stavom. Manažér nad každým driverom uplatní zoznam odvolaní a kľúče cachuje len v rámci požiadavky či jobu.

use RoundlyConsulting\Sentinel\Enums\Algorithm;
use RoundlyConsulting\Sentinel\Enums\KeyStatus;
use RoundlyConsulting\Sentinel\Keys\KeyMaterial;
use RoundlyConsulting\Sentinel\Keys\SealingKey;

$material = KeyMaterial::fromEncoded(Algorithm::Ed25519, $secretFromVault, $publicFromVault);   // base64:… values

return new SealingKey($ring, 'vault-2026-10', $material, KeyStatus::Active, driver: 'vault');

Sentinel zapisuje kľúče (generovanie, rotácia, import, odvolanie, vyradenie) len do vstavaného databázového úložiska kruhu — kruh len s vlastným driverom je pre neho len na čítanie; ak chcete importovať kľúče partnerov za behu, zreťazte vlastný driver s database.

Kotvy

use RoundlyConsulting\Sentinel\Contracts\Anchor;
use RoundlyConsulting\Sentinel\DataTransferObjects\AnchorPayload;

final class ObjectLockAnchor implements Anchor
{
    public function name(): string { return 's3-lock'; }

    public function publish(AnchorPayload $payload): void { /* write it immutably */ }

    public function latest(string $connection): ?AnchorPayload { /* null = write-only */ }
}

Uveďte ju v SENTINEL_ANCHORS=s3-lock; jej voľby patria do ledger.anchor_drivers.s3-lock. Publikovanie beží po commite; výnimka sa zmení na AnchorPublishFailed a ďalší beh to skúsi znova — okrem InvalidSentinelConfigurationException, ktorá sa vyhodí.

Úložiská idempotencie a nonce

use RoundlyConsulting\Sentinel\Contracts\IdempotencyStore;
use RoundlyConsulting\Sentinel\Contracts\NonceStore;

$this->app->bind(IdempotencyStore::class, DynamoIdempotencyStore::class);
$this->app->bind(NonceStore::class, DynamoNonceStore::class);

Úložisko idempotencie musí mať begin() atomické pre každý kľúč — zo súbežných volaní dostane Proceed práve jedno — a dodržať rozhodovaciu tabuľku: iný odtlačok → Reused, platný lease → InProgress s retryAfter, vypršaný lease → prevzatie, dokončené → Replay alebo Unavailable. complete() uspeje len vtedy, kým požiadavka kľúč stále vlastní; consume() a remember() uspejú pre práve jedného volajúceho; upravené či nečitateľné záznamy zlyhajú bezpečne. InMemoryIdempotencyStore a InMemoryNonceStore z fake sú kompaktné referenčné implementácie.

Scope idempotencie

Predvolený Idempotency\RequestScope vráti user:<guard>:<id>, inak sig:<ring>:<kid>, inak ip:<client ip> a kľúč sa ďalej viaže na routu. Ak chcete zmeniť prvú časť, naviažte kontrakt znova:

use Illuminate\Http\Request;
use RoundlyConsulting\Sentinel\Contracts\IdempotencyScopeResolver;

final class TenantScope implements IdempotencyScopeResolver
{
    public function resolve(Request $request): string
    {
        return 'tenant:'.$request->user()?->tenant_id.':user:'.$request->user()?->getKey();
    }
}

$this->app->bind(IdempotencyScopeResolver::class, TenantScope::class);

Politika potvrdenia

use RoundlyConsulting\Sentinel\Contracts\AcknowledgementPolicy;
use RoundlyConsulting\Sentinel\DataTransferObjects\AcknowledgeRequest;

final class TwoPersonRule implements AcknowledgementPolicy
{
    public function authorize(AcknowledgeRequest $request): ?string   // null = allowed, else a denial code
    {
        return Approval::grantedFor($request->model, $request->seal, $request->actor) ? null : 'approval_required';
    }
}

$this->app->bind(AcknowledgementPolicy::class, TwoPersonRule::class);

Zamietnutie vyhodí AcknowledgementDeniedException::unauthorized($code) — rovnako cez fasádu, handle, hromadné potvrdenia aj sentinel:reseal --acknowledge.

Predvolené naviazania

Kontrakt / službaPredvolenéŽivotnosť
SentinelManageron sámsingleton
Contracts\AcknowledgementPolicySupport\GateAcknowledgementPolicybindIf — vyhrá vaše naviazanie
Contracts\IdempotencyScopeResolverIdempotency\RequestScopebindIf
Contracts\IdempotencyStorepodľa idempotency.store (database / cache)pri každom použití; naviazanie v aplikácii ho nahradí
Contracts\NonceStorepodľa nonces.store (database / cache)pri každom použití; naviazanie v aplikácii ho nahradí
továrne úložísk kľúčov a kotiev, skompilované definície—singletony (len kód, žiadny materiál kľúčov)
načítané kľúče, príznaky pozastavenia, služby enginu—scoped: jedna požiadavka alebo job (bezpečné pre Octane)

Manažér si akciu vezme z kontajnera pri každom volaní, takže naviazanie triedy akcie v kontajneri platí všade.

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 kryptomien

Odoslaní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.