merakilab/meraki-core

Meraki Core

Maintainers

Package info

github.com/meraki-labs/meraki-core

pkg:composer/merakilab/meraki-core

Transparency log

Statistics

Installs: 14

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.4 2026-01-02 09:57 UTC

README

merakilab/meraki-core is the foundation package of the Meraki ecosystem. It provides shared conventions, registries, events, and lifecycle hooks that allow independent modules and packages to integrate cleanly — without tight coupling.

Meraki Core does not implement business logic such as roles, authorization engines, or permission storage. It only listens, aggregates, and exposes metadata.

Design Principles

  • Core is neutral: no policy, no storage, no UI
  • Modules declare, Core aggregates
  • IAM decides: authorization logic lives in dedicated packages
  • Event-driven & extensible
  • Convention over enforcement

Package Information

  • Composer name: merakilab/meraki-core
  • Namespace: Meraki\\Core
  • Framework: Laravel / Illuminate components

Core Responsibilities

Meraki Core is responsible for:

  • Registering and bootstrapping the Meraki lifecycle
  • Auto-loading Meraki modules/packages
  • Managing shared configuration conventions
  • Collecting permission metadata from modules
  • Exposing registries, helpers, and events for other packages

Meraki Core is NOT responsible for:

  • Authorization decisions
  • Role management
  • Permission persistence
  • Route protection
  • UI or admin panels

CoreServiceProvider

CoreServiceProvider is the main entry point.

Responsibilities:

  • Register core services and registries
  • Boot lifecycle events
  • Merge and publish shared configuration safely
  • Discover enabled modules
  • Trigger permission collection
use Meraki\Core\CoreServiceProvider;

Permission System (Metadata Only)

Key Concept

Permissions in Meraki Core are declarative metadata, not access rules.

  • Each module declares its own permissions
  • Core collects all declared permissions
  • IAM or other packages decide how to use them

Declaring Permissions in a Module

Each module can declare permissions via its config file, for example:

// config/meraki-blog.php
return [
    'permissions' => [
        'blog.view',
        'blog.create',
        'blog.update',
        'blog.delete',
    ],
];

PermissionRegistry

The PermissionRegistry lives in Core and acts as a central collector.

Responsibilities:

  • Register permissions from all enabled modules
  • Store permission metadata in memory
  • Expose permissions to other packages

Core does not:

  • Validate permissions
  • Resolve conflicts or overlaps
  • Decide access rules

Accessing Permissions

Use the global helper:

get_permissions();

Returns a normalized list of all permissions declared by modules.

Events & Lifecycle Hooks

Meraki Core exposes events so that other packages (e.g. IAM) can hook into the lifecycle.

Examples:

  • Module booted
  • Permissions registered
  • Core fully booted

This allows packages to:

  • Sync permissions to database
  • Build role mappings
  • Attach authorization engines

Without Core knowing how they do it.

Capability Gate

Meraki Core acts as a capability gate — a single access point that routes calls to whichever driver is available, with automatic fallback to Laravel defaults when no Meraki package is installed.

Supported capabilities

Capability Contract Default (fallback)
auth Meraki\Core\Contracts\AuthDriver LaravelAuthAdapter (wraps Auth facade)
permission Meraki\Core\Contracts\PermissionDriver LaravelGateAdapter (wraps Gate facade)

Usage

// Via Facade
Meraki::auth()->check();          // bool
Meraki::auth()->id();             // mixed
Meraki::auth()->user();           // ?object
Meraki::can('posts.create');      // bool
Meraki::can('posts.edit', $user); // bool — check for a specific user

// Via helpers
meraki()->auth()->check();
meraki_can('posts.create');

Driver resolution order

For each capability, CoreManager resolves the driver as follows:

  1. config('meraki.capabilities.<capability>.driver') — explicit name (not auto)
  2. Last driver registered via extend() (package driver)
  3. Laravel adapter (built-in fallback)

Registering a package driver (convention for Meraki packages)

In your package's ServiceProvider::register():

use Meraki\Core\CoreManager;

public function register(): void
{
    $core = $this->app->make(CoreManager::class);

    // Register the package so Core knows it's installed
    $core->packages()->register('meraki-auth', [
        'provider' => static::class,
        'config'   => 'meraki-auth',   // key used to load permissions from config
    ]);

    // Register the capability driver
    $core->extend('auth', 'meraki-auth', fn ($app) => new MerakiAuthDriver(
        $app->make(\Meraki\Auth\Services\AuthManager::class)
    ));
}

MerakiAuthDriver is a thin adapter inside your package that implements Meraki\Core\Contracts\AuthDriver.

Registering a third-party driver (e.g. spatie/laravel-permission)

// In AppServiceProvider::register()
$this->app->make(\Meraki\Core\CoreManager::class)
    ->extend('permission', 'spatie', fn ($app) => new SpatiePermissionDriver());

Then in config/meraki.php:

'capabilities' => [
    'permission' => ['driver' => 'spatie'],
],

Or set MERAKI_PERMISSION_DRIVER=spatie in .env.

Authorization & IAM Integration

Meraki Core defines conventions, not implementations.

  • Core expects IAM packages to expose methods like can()
  • Laravel's Gate::can() can be used, but is optional
  • IAM packages may wrap, replace, or ignore Laravel Gate

Core treats this as a documented convention, not a hard dependency.

Enable / Disable Modules

Modules can be enabled or disabled via configuration.

Core only:

  • Detects enabled modules
  • Loads their configs
  • Registers their permissions

Behavior differences are handled by consuming packages.

Relationship with Other Packages

meraki-iam (example)

Typical responsibilities:

  • Persist permissions
  • Manage roles and scopes
  • Resolve permission conflicts
  • Implement can() / authorization logic
  • Integrate with routes and middleware

Other Feature Packages

  • Declare permissions
  • Listen to Core events
  • Remain independent of IAM implementation

Debugging

Use the meraki:info Artisan command to inspect the current state of the Capability Gate — useful when a driver isn't resolving as expected:

php artisan meraki:info

Sample output:

  Meraki Core — Driver State
  ────────────────────────────────────────
  Capability  Driver              Class
  auth        auto → laravel      Meraki\Core\Adapters\LaravelAuthAdapter
  permission  auto → laravel      Meraki\Core\Adapters\LaravelGateAdapter

  Registered Packages (PackageRegistry)
  ────────────────────────────────────────
  (none)

  Permission Registry: 0 permissions loaded

When a package like meraki-auth is installed, its driver and permissions will appear in the output.

Testing

InteractsWithMerakiCore Trait

Packages that integrate with Meraki Core can use this trait in their test classes to reduce boilerplate:

use Meraki\Core\Testing\InteractsWithMerakiCore;
use Orchestra\Testbench\TestCase;

class MyPackageTest extends TestCase
{
    use InteractsWithMerakiCore;

    public function test_my_driver_works(): void
    {
        $fakeDriver = new class implements \Meraki\Core\Contracts\PermissionDriver {
            public function can(string $permission, mixed $user = null): bool
            {
                return $permission === 'do.something';
            }
        };

        $this->registerFakeDriver('permission', 'fake', $fakeDriver);

        $this->assertMerakiCan('do.something');
        $this->assertMerakiCannot('do.something.else');
    }
}

Available helpers:

Method Description
registerFakeDriver(string $capability, string $name, object $driver) Register a fake driver and set it as the active driver for the capability
assertMerakiCan(string $permission, mixed $user = null) Assert that CoreManager::can() returns true
assertMerakiCannot(string $permission, mixed $user = null) Assert that CoreManager::can() returns false

Note: The src/Testing/ directory is intended for use in tests only. It is mapped under autoload-dev and should not be relied upon in production code.

Summary

Meraki Core is the contract layer of the Meraki ecosystem.

It:

  • Connects packages
  • Aggregates metadata
  • Emits lifecycle events
  • Stays out of business logic

This keeps the system:

  • Modular
  • Replaceable
  • Testable
  • Long-term maintainable

License

MIT