PHP code example of milpa / auth

1. Go to this page and download the library: Download milpa/auth library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

milpa / auth example snippets


use Milpa\Auth\Actor;
use Milpa\Auth\ActorType;
use Milpa\Auth\AuthContext;
use Milpa\Auth\Credential;

// An Actor is a verified identity: who is acting, and what they may do.
$actor = new Actor(
    id: 'u-42',
    type: ActorType::User,          // User | Agent | Service — a closed set, because it is identity
    scopes: ['posts:read', 'posts:write'],
    claims: ['email' => '[email protected]'],
);

// An AuthContext is the trusted answer to "who is this, and may we trust it?"
$ctx = AuthContext::authenticated($actor);

$ctx->isAuthenticated();          // true
$ctx->hasScope('posts:read');     // true
$ctx->hasScope('posts:delete');   // false — fail-closed, an absent scope is denied
$ctx->hasAnyScope(['a', 'b']);    // false

// No credential? An anonymous context — distinct from a *rejected* one.
AuthContext::anonymous()->isAuthenticated();   // false
AuthContext::anonymous()->hasScope('*');       // false — no actor, so nothing is granted

// A bad credential? An invalid context, with the reason recorded — not the same as anonymous.
AuthContext::invalid('expired token')->state;  // AuthState::Invalid

$agent = new Actor('bot-1', ActorType::Agent, scopes: ['*']);
$agent->hasScope('anything-at-all');   // true — '*' is the one explicit escape hatch

$scoped = new Actor('u-1', ActorType::User, scopes: ['posts:*']);
$scoped->hasScope('posts:read');       // false — 'posts:*' is NOT a wildcard, only bare '*' is

$cred = Credential::bearer('the-real-token');

print_r($cred);              // ['type' => 'bearer', 'value' => '[redacted]']
json_encode($cred);          // {"type":"bearer"}  — the value is private, never serialised
serialize($cred);            // throws LogicException — a Credential must never be persisted
clone $cred;                 // throws LogicException — a Credential must never be duplicated
(string) $cred;              // Error — no __toString; a Credential is not a string

$cred->value();              // "the-real-token" — the one deliberate way out, for the verifier

$catalog  = ArrayPermissionCatalog::fromArray([
    'roles' => ['editor' => ['permissions' => ['crm.contact:update']]],
]);
$resolver = new CatalogPermissionResolver($catalog);
$actor    = new Actor('u1', ActorType::User, roles: ['editor']);
$ctx      = AuthContext::authenticated($actor)->withPermissions($resolver->resolve($actor, PermissionContext::none()));

$ctx->can('contact', 'update', 'crm');   // true — via role "editor"
$ctx->permissions()?->sourcesOf(Permission::parse('crm.contact:update'))[0]->id;   // "editor"

new RequirePermissionMiddleware(
    es once per request when no PermissionSet is attached yet
);

use Milpa\Auth\SessionRecord;

$record->isValid($now);   // false if expired as of $now, or revoked — fail-closed
$record->toActor();       // the live Actor the enforcer authorizes against

use Milpa\Auth\InMemorySessionStore;

$store = new InMemorySessionStore(fn () => new DateTimeImmutable('2026-01-01 00:00:00'));
$store->write($record);
$store->read($record->id);   // the record — or null if it is expired/revoked as of the clock