Download the PHP package phpdot/iam without Composer
On this page you can find all versions of the php package phpdot/iam. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package iam
Short Description Identity and access management for the PHPdot ecosystem — staged policy-driven authentication, typed permissions, and policy-class authorization. No policy engine, no DSL.
License MIT
Informations about the package iam
phpdot/iam
This is an experimental package. The API surface may change in any release without a deprecation cycle — pin the constraint and read the release notes before upgrading.
Identity and access management for the PHPdot ecosystem: staged, policy-driven authentication (password plus any further factors, resumed across requests), typed permission keys declared as attributes and mirrored into storage, and policy-class authorization over explicit identity and typed resource objects. No policy engine, no DSL — a permission is membership, a policy is a class you wrote.
Table of Contents
- Requirements
- Installation
- Usage
- Storage contract
- Architecture
- Testing
- License
Requirements
| Requirement | Constraint |
|---|---|
| PHP | >= 8.5 |
ext-mbstring |
* |
phpdot/attribute |
^0.5 |
phpdot/console |
^0.5 |
phpdot/contracts |
^0.5 |
psr/clock |
^1.0 |
psr/container |
^2.0 |
symfony/console |
^8.0 |
phpdot/container is a dev-only suggestion for the binding attributes; phpdot/http and
phpdot/session are suggested for hosts wiring the authorization edge as middleware and running
the session-backed authenticator.
Installation
Usage
Declare permissions on catalog class constants — the constant's value is the key (single source of
truth), the attribute carries the metadata. App code references the constant, so a mistyped
permission is a static-analysis error, not a silent deny. iam:permission:sync finds them and
mirrors them into storage at deploy:
Authorization is two verbs on the scoped AuthorizerInterface — possession (has, hasAny,
hasAll) and policy (can). Every verb fails closed: an empty permission list answers false,
an unknown key is a grant nobody holds, and a context with no identity denies everything.
Authentication is staged: each stage proves one factor, an AuthenticationPolicy decides how many
factors a login needs, and a half-finished login parks in the pending-auth store — namespaced away
from the authenticated session, expiring after a TTL — until the remaining factors arrive or the
attempt fails. Every attempt runs through a LoginThrottleInterface seam: a closed throttle
refuses before any stage (and its Argon2id cost) runs; bind a cache- or table-backed limiter, the
default lets everything through.
The iam:* CLI (over phpdot/console) administers the result: iam:permission:sync,
iam:permission:list, iam:policy:list, iam:role:create, iam:role:delete, iam:role:grant,
iam:role:revoke, iam:role:list, iam:assign, iam:unassign, iam:has, and iam:why. Every
command addresses roles and mirrored permissions by id; the list commands take --q, --page
and --limit.
Storage contract
The package owns the engine; the host owns storage. Four repository contracts, the permission
mirror's read half, and the two catalogs (PermissionCatalogInterface, PolicyCatalogInterface)
are implemented by the host against its own schema. Reads take a FilterDTO (q, named filters,
page/perPage) and answer a SearchDTO composing a Paginator of entity DTOs — there is no
unfiltered all(): a list without a question does not exist. Mutations arrive as SaveDTOs and
address roles and mirrored permissions by id — a name is unique data a person reads, never an
address. Permission keys stay strings exactly where a key is the currency: the check path
(has, hasAny, hasAll, can) and permissionsOf(). Terms every adapter must hold:
- Reserved system roles —
rootandguestalways exist, are undeletable, androotimplies every permission.guestcarries the grants an anonymous actor holds. - Permission status — the closed vocabulary
active/orphaned. A key the scanner no longer declares isorphaned, granting it is refused, and grant resolution over it answers false: un-declaring a permission revokes it. - Grants validate against the mirror —
DefaultRoleManagerreads the mirrored permission row by id (existence, root-only flag, life-stage) before persisting an edge; the catalog serves checks and sync, not grant validation. - Failures fail loudly — an assignment to a nonexistent identity is a storage error that
surfaces to the caller, never a silent no-op (
INSERT IGNOREdowngrading a foreign-key violation to a warning violates this contract). - Identity ids are strings — the package never narrows them; adapters map to their column type without coercing through an integer cast.
- Deterministic order — repositories order internally with an id tiebreak so page boundaries are stable; the filter carries no sort (ordering joins it the day it is asked for).
Architecture
DefaultAuthorizer is request-scoped over an IdentityContext; it resolves an actor's effective
permissions once through the PermissionProviderInterface (assignments joined to role grants) and
answers possession questions by membership. IamScan walks the declared paths with
phpdot/attribute and produces the permission and policy inventory that iam:permission:sync
mirrors into storage. The AuthenticationEngine runs stages to an AuthenticationPolicy's
satisfaction, parking partial attempts in a PendingAuthStoreInterface.
Testing
License
MIT.
This repository is a read-only mirror, generated by CI from phpdot/monorepo. Pull requests and issues belong in the monorepo.
All versions of iam with dependencies
ext-mbstring Version *
phpdot/attribute Version ^0.6
phpdot/console Version ^0.6
phpdot/contracts Version ^0.6
psr/clock Version ^1.0
psr/container Version ^2.0
symfony/console Version ^8.0