{"id":37235462,"url":"https://github.com/teresko/palladium","last_synced_at":"2026-01-16T04:51:08.316Z","repository":{"id":57066829,"uuid":"88082879","full_name":"teresko/palladium","owner":"teresko","description":"User authentication and registration component","archived":false,"fork":false,"pushed_at":"2020-09-24T11:43:14.000Z","size":425,"stargazers_count":43,"open_issues_count":1,"forks_count":9,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-08-01T20:00:17.123Z","etag":null,"topics":["authentication","login","php-library"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/teresko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-12T18:18:09.000Z","updated_at":"2025-03-12T18:14:20.000Z","dependencies_parsed_at":"2022-08-24T14:54:02.836Z","dependency_job_id":null,"html_url":"https://github.com/teresko/palladium","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/teresko/palladium","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teresko%2Fpalladium","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teresko%2Fpalladium/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teresko%2Fpalladium/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teresko%2Fpalladium/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/teresko","download_url":"https://codeload.github.com/teresko/palladium/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teresko%2Fpalladium/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","login","php-library"],"created_at":"2026-01-15T04:02:31.638Z","updated_at":"2026-01-15T04:02:32.492Z","avatar_url":"https://github.com/teresko.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Palladium\n\n**(work-in-progress: docs for 2.0)**\n\n[![Build Status](https://travis-ci.org/teresko/palladium.svg?branch=master)](https://travis-ci.org/teresko/palladium)\n[![Packagist Version](https://img.shields.io/packagist/v/teresko/palladium.svg)](https://packagist.org/packages/teresko/palladium)\n[![License](https://img.shields.io/packagist/l/teresko/palladium.svg)](https://github.com/teresko/palladium/blob/master/LICENSE.md)\n[![Code Climate](https://codeclimate.com/github/teresko/palladium/badges/gpa.svg)](https://codeclimate.com/github/teresko/palladium)\n[![Code Coverage](https://scrutinizer-ci.com/g/teresko/palladium/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/teresko/palladium/?branch=master)\n[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/teresko/palladium.svg)](https://scrutinizer-ci.com/g/teresko/palladium/?branch=master)\n[![Infection MSI](https://badge.stryker-mutator.io/github.com/teresko/palladium/master)](https://infection.github.io)\n\n\nLibrary for handling the user identification.\n\nThe purpose of this library is to locate user's [account](https://github.com/teresko/palladium/blob/master/docs/Concept/Account.md) (to be precise - its unique id) for a given proof of [identity](https://github.com/teresko/palladium/blob/master/docs/Concept/Identity.md) and to manage various types of identities. It consists of 4 different [services](https://github.com/teresko/palladium/blob/master/docs/Concept/Service.md): Identification, Registration, Search and Recovery.\n\n\n## Installation\n\nYou can add the library to your project using composer with following command:\n\n```sh\ncomposer require teresko/palladium\n```\n\nTo use this package, it require PHP version 7.0+ and PDO.\n\nYou will also need to create a table, where to store the **identities**. The example schema is available [here](https://github.com/teresko/palladium/blob/master/resources/schema.sql). It currently contains only table definition for MySQL/MariaDB, but the library can be used with any RDBMS, that has a PDO driver.\n\n\n## Initialization\n\n\nPalladium contains 4 services: `Registration`, `Identification`, `Search` and `Recovery`. Each of these services has two\u0026nbsp;mandatory\u0026nbsp;dependencies:  \n\n - repository (that implements `Palladium\\Contract\\CanPersistIdenity`)\n - logger (that implements `Psr\\Log\\LoggerInterface`)\n\n\n This gives you an option to replace the default  [repository](https://github.com/teresko/palladium/blob/master/src/Palladium/Repository/Identity.php), if you want to alter or replace parts of persistence abstraction\u0026nbsp;layer. As for logger - the recommended approach is to use [Monolog](https://packagist.org/packages/monolog/monolog), but it would work with any compatible logging\u0026nbsp;system.\n\n\nThe default repository also comes with functionality for adding **custom identity types** and data mappers, that are used for either your or the built-in identity types. For usage details see %TODO% section.\n\n#### Optional parameters\n\nIn the constructor of `Identification` service there is an optional third and fourth parameter:\n\n- lifespan of the cookie (in seconds), which defaults to 4 hours.\n- hash cost (for BCrypt), which defaults to 12\n\nIn the constructor of `Registration` service there is an optional third parameter:\n\n- hash cost (for BCrypt), which defaults to 12\n\n#### Setting up the repository\n\nAs noted above, all 4 of the services expect a repository as a constructor dependency. If you are not replacing the bundled repository with your custome version, then you will need to initialize `Palladium\\Repository\\Identity` and pass it to the services.\n\nThe bundled repository itself has a single dependency: instance, that implements `Palladium\\Contract\\CanCreateMapper`. This contract (interface) is implemented by `Palladium\\Component\\MapperFactory`. And this factory has two dependencies: `PDO` instance and the name of table, where the **identities** will be stored.\n\n```php\n\u003c?php\n\n$factory = new \\Palladium\\Component\\MapperFactory(new \\PDO(...$config), $tableName);\n$repository = new \\Palladium\\Repository\\Identity($factory);\n```\n\nIn every other code example, where you see `$repository` variable used, you can assume, that it has been initialized using this code sample.\n\n#### Use with DI containers\n\nFor users of Symfony's [DependencyInjection Component](https://symfony.com/doc/current/components/dependency_injection.html) (version: 3.4+), there is a sample configuration file: %TODO%\n\n\n## Usage\n\n\n#### Registration of new identity\n\n```php\n\u003c?php\n\n$registration = new \\Palladium\\Service\\Registration($repository, $logger);\n\n$identity = $registration-\u003ecreateStandardIdentity('foo@bar.com', 'password');\n$registration-\u003ebindAccountToIdentity($accountId, $identity);\n```\n\nIf operation is completed successfully, the `$identity` variable will contain an instance of unverified [`StandardIdentity`](https://github.com/teresko/palladium/blob/master/src/Palladium/Entity/StandardIdentity.php). To complete verification, you will have to use the token, that the identity contains. In the give example, this token can be assessed using\u0026nbsp;`$instance-\u003egetToken()`.\n\nThe `createStandardIdentity()` method can throw  [`IdentityConflict`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityConflict.php) exception, if email has already used for a another\u0026nbsp;identity.\n\nThe `createStandardIdentity()` method has an optional third parameter, that defines the lifespan on the email verification token in seconds. When applied, the previous example looks as following:\n\n```php\n\u003c?php\n\n$registration = new \\Palladium\\Service\\Registration($repository, $logger);\n\n$identity = $registration-\u003ecreateStandardIdentity('foo@bar.com', 'password', 3600);\n$registration-\u003ebindAccountToIdentity($accountId, $identity);\n```\n\nThis will make the verification token usable for 1 hour after this user's identity has been registered. After that given time passes, you won't be able to find this identity using the `findStandardIdentityByToken()` in the `Search` service.\n\n\u003e **IMPORTANT**: the `createStandardIdentity()` methods does not validate users email or any other type of identifier. It only checks its uniqueness. Validation of emails, phone numbers, nicknames and other identifiers is beyond the scope of this library.\n\n#### Verification of an identity\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$registration = new \\Palladium\\Service\\Registration($repository, $logger);\n\n$identity = $search-\u003efindStandardIdentityByToken($token, \\Palladium\\Entity\\Identity::ACTION_VERIFY);\n$registration-\u003everifyStandardIdentity($identity);\n```\n\nThe `$token` value is used to locate the matching [`EmailIdentity`](https://github.com/teresko/palladium/blob/master/src/Palladium/Entity/StandardIdentity.php), which then gets verified. If the identity is not found, the `findStandardIdentityByToken()` will throw [`IdentityNotFound`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityNotFound.php) exception.\n\n#### Login with email and password\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$identification = new \\Palladium\\Service\\Identification($repository, $logger);\n\n$identity = $search-\u003efindStandardIdentityByIdentifier($identifier);\n$cookie = $identification-\u003eloginWithPassword($identity, $password);\n```\n\nIf there is no matching identity with given idenitifier (like, email address) found, the `findStandardIdentityByIdentifier()` method will throw [`IdentityNotFound`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityNotFound.php) exception.\n\nIn case, if password does not match, the `loginWithPassword()` method will throw [`PasswordMismatch`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/PasswordMismatch.php) exception.\n\n#### Creation of new single-use login\n\n```php\n\u003c?php\n\n$identity = $this-\u003eregistration-\u003ecreateNonceIdentity($accountId);\n```\n\nThis will create a new instance of `NonceIdentity`. To use it for login, you will need values in `NonceIdentity::getIdentifier()` and `NonceIdentity::getKey()`, where the identifier will be used to locate the nonce identity and key will be used to verify.\n\nThe `createNonceIdentity()` method was an optional second parameter, that defines the lifespan this single-use identity in seconds. When applied, the previous example looks as following:\n\n```php\n\u003c?php\n\n$identity = $this-\u003eregistration-\u003ecreateNonceIdentity($accountId, 600);\n```\n\nThis will make the single-use identity usable for 10 minutes after its creation. After the allowed time has passed, passing this identity in `useNonceIdentity()` method of `Identification` will result in [`IdentityExpired`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityExpired.php) exception being thrown.\n\n#### Login with nonce\n\n```php\n\u003c?php\n\n$identity = $this-\u003esearch-\u003efindNonceIdentityByIdentifier($identifier);\n$cookie = $this-\u003eidentification-\u003euseNonceIdentity($identity, $key);\n```\n\nIf there is no matching identity with given identitifier (email address, nickname, ect.) found, the `findNonceIdentityByIdentifier()` method will throw [`IdentityNotFound`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityNotFound.php) exception.\n\nIn case, if password does not match, the `useNonceIdentity()` method will throw [`KeyMismatch`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/KeyMismatch.php) exception.\n\n\n#### Login using cookie\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$identification = new \\Palladium\\Service\\Identification($repository, $logger);\n\n$identity = $search-\u003efindCookieIdentity($accountId, $series);\n$cookie = $identification-\u003eloginWithCookie($identity, $key);\n```\n\nIf cookie is not found using `findCookieIdentity()` a standard [`IdentityNotFound`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityNotFound.php) exception will be thrown. The possible caused for it would be either cookie not being active anymore (e.g. user logged out) or cookie not existing at all.\n\nIn case, if cookie is too old, `loginWithCookie()` will produce [`IdentityExpired`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityExpired.php) exception.\n\nBut the `loginWithCookie()` method can also produce [`CompromisedCookie`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/CompromisedCookie.php) exception. Seeing an exception for this **could indicate, that cookie has been stolen** or that user never received a new cookie value.\n\n\n#### Blocking a compromised cookie\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$identification = new \\Palladium\\Service\\Identification($repository, $logger);\n\n$identity = $search-\u003efindCookieIdentity($accountId, $series);\n$identification-\u003eblockIdentity($identity);\n```\n\nThis is the recommended way for dealing with suspicious cookies, that might or might not be stolen. This is **not intended for logging out users**.\n\n#### Logout\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$identification = new \\Palladium\\Service\\Identification($repository, $logger);\n\n$identity = $search-\u003efindCookieIdentity($accountId, $series);\n$identification-\u003elogout($identity, $key);\n```\n\nThis operation marks the cookie as \"discarded\". The list of exception, that can be produced, match the ones described in [login using cookie](#login-using-cookie) section.\n\n#### Initiating password reset process\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$recovery = new \\Palladium\\Service\\Recovery($repository, $logger);\n\n$identity = $search-\u003efindStandardIdentityByIdentifier($identifier);\n$token = $recovery-\u003emarkForReset($identity);\n```\n\nIf there is no matching identity with given email address found, the `findStandardIdentityByIdentifier()` method will throw [`IdentityNotFound`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityNotFound.php) exception.\n\nWhen `markForReset()` is called, it must be provided with an instance of `StandardIdentity`, that has already been verified (otherwise, it has a potential to leak user's private information from your application). If that is not the case, the method will throw [`IdentityNotVerified`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityNotVerified.php) exception.\n\nThe `markForReset()` method was an optional second parameter, that defines the lifespan on the password reset token in seconds. When applied, the previous example looks as following:\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$recovery = new \\Palladium\\Service\\Recovery($repository, $logger);\n\n$identity = $search-\u003efindStandardIdentityByIdentifier($identifier);\n$token = $recovery-\u003emarkForReset($identity, 7200);\n```\n\nThis will make the password reset token usable for two hours after this user's identity has been marked for reset. When the allowed time has expired, you won't be able to find this identity using the `findEmailIdentityByToken()` in the `Search` service.\n\n#### Completion of password reset\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$recovery = new \\Palladium\\Service\\Recovery($repository, $logger);\n\n$identity = $search-\u003efindEmailIdentityByToken($token, \\Palladium\\Entity\\Identity::ACTION_RESET);\n$recovery-\u003eresetIdentityPassword($identity, 'foobar');\n```\n\nIf there is no matching identity with given token found, the `findEmailIdentityByToken()` method will throw [`IdentityNotFound`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityNotFound.php) exception.\n\n#### Changing password of email identity\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$identification = new \\Palladium\\Service\\Identification($repository, $logger);\n\n$identity = $search-\u003efindStandardIdentityByIdentifier($identifier);\n$identification-\u003echangePassword($identity, $oldPassword, $newPassword);\n```\n\nIf there is no matching identity with given email address (or any other type of identifier) found, the `findStandardIdentityByIdentifier()` method will throw [`IdentityNotFound`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/IdentityNotFound.php) exception.\n\nIn case, if the password does not match, the `changePassword()` method will throw [`PasswordMismatch`](https://github.com/teresko/palladium/blob/master/src/Palladium/Exception/PasswordMismatch.php) exception.\n\n#### Logging out identities in bulk\n\n```php\n\u003c?php\n\n$search = new \\Palladium\\Service\\Search($repository, $logger);\n$identification = new \\Palladium\\Service\\Identification($factory, $logger);\n\n$list = $search-\u003efindIdentitiesByParentId($identity-\u003egetId());\n$identification-\u003ediscardIdentityCollection($list);\n```\n\nThe return value of `findIdentitiesByParentId()` will return `IdentityCollection`, which can be empty.\n\n## Logging of user activity\n\nAs previously mentioned, the services in this library expect a [PSR-3 compatible](https://github.com/php-fig/log) logger as a dependency. It will be utilized to log three levels of events:\n\n#### `LogLevel::INFO`\n\nThis log-level is used for tracking ordinary operations, that user would perform, when using your application in the intended manner:\n\n - successful registration\n - successful password recover\n - successful login (with email/username or cookie) or logout\n - successful email verification\n - use of expired cookie or nonce\n\n#### `LogLevel::NOTICE`\n\nLogs with this level will be recorded, if user attempted an unsuccessful operation, that should not happed in correct usage scenarios:\n\n - all cases, when identity was not found\n - incorrect password was entered\n - identifier already used for different identity\n - attempt to recover password using unverified email\n\n#### `LogLevel::WARNING`\n\nOnly used for logging cases, when user attempted to use a compromised cookie.\n\n\n\n## Additional notes\n\nThis library focuses on one specific task. It **does not** include any of the following functionality:\n\n - account creation and management\n - authorization system\n - validation of user input (including emails and passwords)\n - logging framework\n\nIf you think, that authentication library requires one of the above listed parts, then this is not the library that you are looking for.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteresko%2Fpalladium","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteresko%2Fpalladium","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteresko%2Fpalladium/lists"}