Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Vault Laravel Package

rappasoft/vault

Rappasoft Vault gives Laravel apps an encrypted key-value store for secrets and credentials. Keep API keys, tokens, and other sensitive values in the database instead of config files or source control, and retrieve them through a simple facade.

View on GitHub
Deep Wiki
Context7

Getting Started

Vault is a Laravel 5-era roles & permissions package: a VaultUser trait on your User model, Role/Permission Eloquent models, pivot tables, Blade directives, and route middleware. The repo is archived, so treat it as "maintenance mode" — use it because your Laravel 5.x app already depends on it, not for greenfield work (for new projects reach for spatie/laravel-permission).

Minimal setup in an existing L5 app:

composer require rappasoft/vault

Register the provider in config/app.php:

Rappasoft\Vault\VaultServiceProvider::class,

Publish config and migrations, then migrate:

php artisan vendor:publish --provider="Rappasoft\Vault\VaultServiceProvider"
php artisan migrate

Add the trait to your user model:

use Rappasoft\Vault\Traits\VaultUser;

class User extends Authenticatable
{
    use VaultUser;
}

Register the middleware aliases in app/Http/Kernel.php so routes stay readable:

protected $routeMiddleware = [
    // ...
    'role'       => \Rappasoft\Vault\Middleware\CheckRole::class,
    'permission' => \Rappasoft\Vault\Middleware\CheckPermission::class,
];

Where to look first: config/vault.php (model bindings, table names), the published migrations, and vendor/rappasoft/vault/src/Traits/VaultUser.php — that trait is the real API surface and the file you'll be reading whenever a check misbehaves.

First use case — protect one admin route and one button:

Route::get('/admin', 'AdminController@index')->middleware('role:admin');

// anywhere you have a $user
if ($user->hasPermission('users.delete')) { /* ... */ }
@role('admin')
    <a href="/admin">Admin</a>
@endrole

Implementation Patterns

Seed roles and permissions idempotently. Never hardcode IDs; roles and permissions are data that differ per environment.

// database/seeds/RolesAndPermissionsSeeder.php
$admin = Role::firstOrCreate(['name' => 'admin']);
$editor = Role::firstOrCreate(['name' => 'editor']);

foreach (['posts.create', 'posts.edit', 'posts.delete', 'users.delete'] as $name) {
    Permission::firstOrCreate(['name' => $name]);
}

$editor->attachPermission(Permission::where('name', 'posts.edit')->first());

Then $this->call(RolesAndPermissionsSeeder::class); from DatabaseSeeder, and run it in every deploy pipeline (including staging and CI, where migrate:fresh --seed is normal).

Assign at the boundary, check deep inside. Assign roles in registration/onboarding/seeders, then only check in controllers, policies, and views. A useful split:

// Registration / admin action
$user->assignRole('editor');

// Controller
public function destroy(Post $post)
{
    abort_unless(auth()->user()->hasPermission('posts.delete'), 403);
    $post->delete();
}

Route middleware for coarse access, permission checks for fine access. Roles gate whole areas (/admin/*), permissions gate individual actions. Middleware accepts multiple arguments in the usual Laravel comma syntax (->middleware('role:admin,manager')) — verify the semantics in CheckRole before relying on "any of" vs "all of".

Prefer permissions in code, roles in UI. Naming roles in hasRole('admin') sprinkled through controllers makes renaming a role a refactor. Where practical, check permissions and let admins compose roles from them. If you must check roles, define constants on a small Roles class so typos fail loudly.

Wrap it in a policy layer so the rest of the app talks to Laravel's authorization, not to Vault:

class PostPolicy
{
    public function update(User $user, Post $post)
    {
        return $user->hasPermission('posts.edit')
            || $user->id === $post->user_id;
    }
}

Now $this->authorize('update', $post) and @can('update', $post) work, and swapping the underlying package later only touches policies.

Eager-load for menu rendering. If your nav renders role/permission-gated links on every page, load relations once:

$user = User::with('roles.permissions')->find(auth()->id());

Test the matrix, not the widget. Seed roles/permissions in setUp, then assert with $this->actingAs($editor)->get('/posts/create')->assertStatus(200) and the 403 counterpart. Because authorization is data-driven, tests that don't seed permissions silently "pass" as denied — always assert the positive case too.

Gotchas and Tips

  • Archived means frozen. No PHP 8 / Laravel 6+ compatibility work, no security patches. Pin your PHP version in composer.json, and if you're planning an upgrade, budget a migration to spatie/laravel-permission as part of it rather than fighting the constraints. The data model (roles, permissions, pivots) maps across reasonably well, so plan a data migration, not a rewrite.
  • can() collision. Vault's trait methods and Laravel's Gate can look like competing sources of truth. Pick one vocabulary (hasPermission() for Vault, @can/authorize() for policies) and don't mix them in the same file, or you'll get "why is this 403" bugs that are actually a check against the wrong system.
  • Middleware must be aliased. With no aliases in Kernel.php, ->middleware('role:admin') throws a BindingResolutionException. Also re-check Kernel.php after framework-level upgrades that overwrite it.
  • Stale relations after mutation. After assignRole()/attachPermission(), an already-loaded roles relation on that instance can be out of date. Call $user->load('roles', 'permissions') or $user->refresh() before asserting in tests and before rendering the nav in the same request.
  • Config cache. php artisan config:cache snapshots the model bindings in config/vault.php. After changing custom role/permission models, clear it (config:clear) — otherwise you get confusing "class not found" or silently default models.
  • Custom models are the extension point. Point config/vault.php at your own Role/Permission subclasses to add behavior (e.g. a display_name, or extra pivot data). Don't edit vendor/ — the trait and models are the seams you're meant to override.
  • Deletion leaves orphans. Removing a role may leave pivot rows behind depending on your migration's foreign-key/cascade setup; check the published migrations and add onDelete('cascade') if you're seeing ghost permissions survive a role delete.
  • Typos fail closed but silently. hasPermission('posts.edit') vs posts.edits returns false with no warning, so a gated button just disappears. Keep permission names in constants or config and reference them from both seeders and checks.
  • Debugging workflow: dump $user->roles->pluck('name') and $user->permissions->pluck('name') at the point of failure. Nine times out of ten it's "the seeder never ran in this environment" or "the role exists but the permission was never attached to it" — permissions on roles and permissions on users are separate paths, so check both.
  • Don't build an admin UI on top of the vendor views (if you go that route). Keep your own CRUD in your app so a future package swap doesn't delete your screens.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect