Every row sharing a context value uses one DEK. KEK rotation rewraps one DB row per context. Best for multi-tenant SaaS.
Configure
use Crumbls\Sealcraft\Casts\Encrypted;
use Crumbls\Sealcraft\Concerns\HasEncryptedAttributes;
class Document extends Model
{
use HasEncryptedAttributes;
protected string $sealcraftContextType = 'tenant';
protected string $sealcraftContextColumn = 'tenant_id';
protected $casts = ['body' => Encrypted::class];
}
How it works
Sealcraft looks up (or mints) one DataKey row per (context_type, context_id) pair. Every Document where tenant_id = 42 shares the DEK at ('tenant', 42).
Read workload:
- First read per request for tenant 42: one
sealcraft_data_keyslookup + one KEK unwrap call - Every subsequent read for tenant 42 in the same request: zero network calls (DEK cached in memory)
When to use
- Multi-tenant SaaS where each tenant is the unit of trust
- Apps with a natural aggregate (user, patient, organization) that owns many rows
- Any time "one tenant = one compliance scope"
When to pick something else
- Each row is an independent security boundary -- use per-row
- A user's data spans multiple root-owned tables and you want one shred to destroy it all -- use delegated context
Contributors
Thank you to everyone who has contributed to this package. Every pull request, bug report, and idea makes a difference.