PHPackages                             charcoal/user - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. charcoal/user

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

charcoal/user
=============

User definition, authentication and authorization.

v5.0.0(2y ago)0182MITPHPPHP ^7.4 || ^8.0

Since Jan 19Pushed 2y ago2 watchersCompare

[ Source](https://github.com/charcoalphp/user)[ Packagist](https://packagist.org/packages/charcoal/user)[ RSS](/packages/charcoal-user/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (13)Versions (63)Used By (2)

Charcoal User
=============

[](#charcoal-user)

The User package provides abstract tools for defining user models, authenticating and authorizating users from an integration with [Laminas Permissions ACL](https://github.com/laminas/laminas-permissions-acl).

Installation
------------

[](#installation)

```
composer require charcoal/user
```

Overview
--------

[](#overview)

### The User object

[](#the-user-object)

At the core of this module is the definition of a "User" object. The contract can be found as `\Charcoal\User\UserInterface`. This interfaces extends `\Charcoal\Object\ContentInterface` (from `charcoal/object`), which extends `\Charcoal\Model\ModelInterface` (from `charcoal/core`).

The preferred way of using this module is by defining your own User class in your project and extending the provided `\Charcoal\User\AbstractUser` class.

For quick prototypes or small projects, a full concrete class is provided as `\Charcoal\User\GenericUser`.

#### User properties

[](#user-properties)

PropertyTypeDefaultDescription**username**`string``true`…**password**`string``null`…**email**`string``null`…**roles**`string[]``[]`ACL roles, which define user permissions.**last\_login\_date**`date-time``null`…**last\_login\_ip**`string``''`…**last\_password\_date**`date-time``null`…**last\_password\_ip**`string``''`…**login\_token**`string``null`…> Note that the `key` of the User is the `username`. Therefore, `id()` returns the username. It must be unique.

**Properties inherited from `Content-Interface`:**

PropertyTypeDefaultDescription**active**`boolean``true`…**position**`number``null`…**created**`date-time``null`…**created\_by**`string``''`…**last\_modified**`date-time``null`…**last\_modified\_by**`string``''`…### Authentication

[](#authentication)

TODO

### Authorization

[](#authorization)

User authorization is managed with a role-based *Access Control List* (ACL). Internally, it uses [`laminas/laminas-permissions-acl`](https://github.com/laminas/laminas-permissions-acl) for the ACL logic. It is recommended to read the [Laminas ACL documentation](https://docs.laminas.dev/laminas-permissions-acl/) to learn more about how it all works.

There are 2 main concepts that must be managed, either from JSON config files or in the database (which works well with `charcoal/admin`), **roles** and **permissions**.

#### ACL Configuration

[](#acl-configuration)

To set up ACL, it is highly recommended to use the `\Charcoal\User\Acl\Manager`.

#### ACL Example

[](#acl-example)

```
{
    "acl": {
        "permissions": {
            "superuser": {
                "superuser": true
            },
            "author": {
                "allowed": {},
                "denied": {}
            }
        }
    }
}
```

```
use Charcoal\User\Acl\Manager as AclManager;
use Laminas\Permissions\Acl\Acl;
use Laminas\Permissions\Acl\Resource\GenericResource as AclResource;

$acl = new Acl();

 // Add resource for ACL
$acl->addResource(new AclResource($resourceName));

$aclManager = new AclManager([
    'logger' => $logger,
]);
$aclManager->loadPermissions($acl, $config['acl.permissions'], $resourceName);

$authorizer = new Authorizer([
    'logger'   => $logger,
    'acl'      => $acl,
    'resource' => $resourceName,
]);

$isAllowed = $authorizer->userAllowed($user, [ 'permssion' ]);
```

Resources
---------

[](#resources)

- [Contributing](https://github.com/charcoalphp/.github/blob/main/CONTRIBUTING.md)
- [Report issues](https://github.com/charcoalphp/charcoal/issues) and [send pull requests](https://github.com/charcoalphp/charcoal/pulls)in the [main Charcoal repository](https://github.com/charcoalphp/charcoal)

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity82

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~46 days

Recently: every ~15 days

Total

58

Last Release

796d ago

Major Versions

0.7.0.2 → v2.1.22022-06-21

v2.2.3 → v3.1.02022-08-08

v3.1.8 → v4.0.02022-09-21

v4.1.0 → v5.0.02024-03-13

PHP version history (4 changes)0.1PHP &gt;=5.6.0

0.2.2PHP &gt;=5.6.0 || &gt;=7.0

0.6.4PHP &gt;7.1

v2.1.2PHP ^7.4 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/cfb071c0ff7ce9500c528a003a2c53124248debc3e5bf367c17f89f5e6136125?d=identicon)[mducharme](/maintainers/mducharme)

![](https://www.gravatar.com/avatar/0a4f39523b4b2837562ba0848a0327b8d340118d1ba87cb0f5d59b1d5cb6beba?d=identicon)[mcaskill](/maintainers/mcaskill)

![](https://www.gravatar.com/avatar/f3f29e38395113e2400bdd7e51bea982b17f120d4d5a53d4473b53118ee46f8d?d=identicon)[JoelAlphonso](/maintainers/JoelAlphonso)

![](https://www.gravatar.com/avatar/4229f19eecd12c2b651b6502dcc5adfba48c5770db3d2dbea55fc92c7a246b2b?d=identicon)[BeneRoch](/maintainers/BeneRoch)

---

Top Contributors

[![mcaskill](https://avatars.githubusercontent.com/u/29353?v=4)](https://github.com/mcaskill "mcaskill (64 commits)")[![mducharme](https://avatars.githubusercontent.com/u/12157?v=4)](https://github.com/mducharme "mducharme (39 commits)")[![actions-user](https://avatars.githubusercontent.com/u/65916846?v=4)](https://github.com/actions-user "actions-user (17 commits)")[![dominiclord](https://avatars.githubusercontent.com/u/1775204?v=4)](https://github.com/dominiclord "dominiclord (8 commits)")[![JoelAlphonso](https://avatars.githubusercontent.com/u/10762266?v=4)](https://github.com/JoelAlphonso "JoelAlphonso (8 commits)")[![BeneRoch](https://avatars.githubusercontent.com/u/3017380?v=4)](https://github.com/BeneRoch "BeneRoch (2 commits)")

---

Tags

authenticationauthorizationcharcoalphpread-only-repositoryuser

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/charcoal-user/health.svg)

```
[![Health](https://phpackages.com/badges/charcoal-user/health.svg)](https://phpackages.com/packages/charcoal-user)
```

###  Alternatives

[google/auth

Google Auth Library for PHP

1.4k272.7M162](/packages/google-auth)[simplesamlphp/simplesamlphp

A PHP implementation of a SAML 2.0 service provider and identity provider.

1.1k12.4M193](/packages/simplesamlphp-simplesamlphp)[simplesamlphp/saml2

SAML2 PHP library from SimpleSAMLphp

30317.2M40](/packages/simplesamlphp-saml2)[web-auth/webauthn-lib

FIDO2/Webauthn Support For PHP

1225.3M72](/packages/web-auth-webauthn-lib)[litesaml/lightsaml

SAML 2.0 PHP library

1055.5M18](/packages/litesaml-lightsaml)[web-auth/webauthn-framework

FIDO2/Webauthn library for PHP and Symfony Bundle.

50570.7k1](/packages/web-auth-webauthn-framework)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
