PHPackages                             pps-protocol/laravel-pps - 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. pps-protocol/laravel-pps

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

pps-protocol/laravel-pps
========================

Laravel integration for PulseProof Sentinel Protocol (PPS).

v0.1.0(today)10Apache-2.0PHPPHP ^8.1CI passing

Since Jul 23Pushed todayCompare

[ Source](https://github.com/pps-protocol/laravel-pps)[ Packagist](https://packagist.org/packages/pps-protocol/laravel-pps)[ Docs](https://github.com/pps-protocol/laravel-pps)[ RSS](/packages/pps-protocol-laravel-pps/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (8)Versions (2)Used By (0)

Laravel PPS
===========

[](#laravel-pps)

  **Laravel integration for the PulseProof Sentinel Protocol (PPS)**

 [![Laravel PPS](https://camo.githubusercontent.com/3354ed0afee67bd2df5f56100694135475dfd93796744d2725a9257ed20b859d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d5050532d7265643f7374796c653d666c6174)](https://camo.githubusercontent.com/3354ed0afee67bd2df5f56100694135475dfd93796744d2725a9257ed20b859d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d5050532d7265643f7374796c653d666c6174) [![PHP 8.1+](https://camo.githubusercontent.com/3a73e2280ec14e7ba71344d0c7bcdf21c2f95f4bd8ee037a42fdbd89da744e65/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d373737424234)](https://camo.githubusercontent.com/3a73e2280ec14e7ba71344d0c7bcdf21c2f95f4bd8ee037a42fdbd89da744e65/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d373737424234) [![Laravel 10/11/12/13](https://camo.githubusercontent.com/d18a9b9d389f5dcbeab9f8555024945fdd470786c7c62fb0ebbc6589441edd19/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31302532302537432532303131253230253743253230313225323025374325323031332d464632443230)](https://camo.githubusercontent.com/d18a9b9d389f5dcbeab9f8555024945fdd470786c7c62fb0ebbc6589441edd19/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31302532302537432532303131253230253743253230313225323025374325323031332d464632443230) [![Status: Experimental](https://camo.githubusercontent.com/38607f258b26c40a3ad3a18a5c45902206dad7fdc57add111d06c3afbd078e5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5374617475732d4578706572696d656e74616c2d6f72616e6765)](https://camo.githubusercontent.com/38607f258b26c40a3ad3a18a5c45902206dad7fdc57add111d06c3afbd078e5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5374617475732d4578706572696d656e74616c2d6f72616e6765) [![License: Apache-2.0](https://camo.githubusercontent.com/bbb012395ef1fa09ec910634c05f9b3ac78fa2ab7ac4c9a825fba78b82a1adf7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4170616368652d2d322e302d626c7565)](https://camo.githubusercontent.com/bbb012395ef1fa09ec910634c05f9b3ac78fa2ab7ac4c9a825fba78b82a1adf7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4170616368652d2d322e302d626c7565)

---

Introduction
------------

[](#introduction)

`laravel-pps` is the official Laravel integration package for the **PulseProof Sentinel Protocol**, abbreviated **PPS**.

This package provides:

- Laravel service provider
- Publishable configuration
- API routes
- HTTP controller
- Facade
- Artisan commands
- Database migrations
- Storage backend integration
- Silent duress handling support
- Transaction signing support

The core protocol implementation lives in the framework-agnostic package:

```
pps-protocol/pps-php

```

This package, `pps-protocol/laravel-pps`, depends on `pps-protocol/pps-php` and only adds Laravel-specific integration.

---

What is PPS?
------------

[](#what-is-pps)

PulseProof Sentinel Protocol, or **PPS**, is an experimental authentication protocol based on time-bound asymmetric proofs.

Instead of shared-secret TOTP codes:

```
TOTP = HMAC(shared_secret, time)

```

PPS uses signed asymmetric proofs:

```
Pulse = Sign(private_key, time + rp + nonce + counter + context + policy)

```

The server stores only public keys.

PPS is designed to complement, not replace, WebAuthn/FIDO2.

WebAuthn remains preferred for browser-based passkey authentication.

PPS targets operational gaps such as:

- offline or semi-offline authentication
- legacy OTP-style input flows
- QR-code and deep-link authentication
- constrained hardware terminals
- point-of-sale and IoT devices
- transaction signing with human-visible amount confirmation
- silent duress signaling
- offline multi-device threshold approval

---

Important Links
---------------

[](#important-links)

ResourceLinkPPS Specification[pps-protocol/pulseproof-sentinel](https://github.com/pps-protocol/pulseproof-sentinel)IETF Internet-Draft[draft-hezami-pulseproof-sentinel](https://datatracker.ietf.org/doc/draft-hezami-pulseproof-sentinel/)Core PHP Package[pps-protocol/pps-php](https://github.com/pps-protocol/pps-php)Laravel Package[pps-protocol/laravel-pps](https://github.com/pps-protocol/laravel-pps)Documentation Site[pps-protocol.github.io](https://pps-protocol.github.io)---

Requirements
------------

[](#requirements)

RequirementVersionPHP8.1+Laravel10.x, 11.x, 12.x or 13.xext-sodiumrequiredext-gmprequiredext-hashrequiredext-jsonrequiredThe core package `pps-protocol/pps-php` will be installed automatically.

---

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

[](#installation)

Install via Composer:

```
composer require pps-protocol/laravel-pps
```

Laravel package discovery should automatically register:

```
Pps\Laravel\PulseProofServiceProvider

```

and the facade:

```
Pps\Laravel\Facades\PulseProof

```

If package discovery is disabled, register manually in `config/app.php`:

```
'providers' => [
    Pps\Laravel\PulseProofServiceProvider::class,
],

'aliases' => [
    'PulseProof' => Pps\Laravel\Facades\PulseProof::class,
],
```

---

Publish Configuration and Migrations
------------------------------------

[](#publish-configuration-and-migrations)

Run the install command:

```
php artisan pps:install
```

This publishes:

```
config/pps.php
database/migrations/*_create_pps_tables.php

```

Then run migrations if you are using the PDO storage driver:

```
php artisan migrate
```

---

Configuration
-------------

[](#configuration)

The main configuration file is:

```
config/pps.php

```

You can also configure PPS using environment variables.

```
PPS_RP_ID=example.com
PPS_ALGORITHM=PPS-ED25519-CBOR30
PPS_EPOCH_SECONDS=30
PPS_MAX_CLOCK_SKEW=1
PPS_TRUST_DIGITS=8
PPS_NONCE_TTL=60
PPS_ALLOW_OFFLINE=false

PPS_STORAGE_DRIVER=file
# PPS_STORAGE_DRIVER=pdo
# PPS_DB_CONNECTION=mysql
# PPS_STORAGE_DRIVER=redis
# PPS_REDIS_CONNECTION=default

PPS_ROUTES_ENABLED=true
PPS_ROUTE_PREFIX=pps
PPS_ROUTE_MIDDLEWARE=api
```

### Relying Party Identifier

[](#relying-party-identifier)

The `rp_id` identifies your service.

Examples:

```
example.com
login.example.com
localhost

```

For local development:

```
PPS_RP_ID=localhost
```

---

Storage Drivers
---------------

[](#storage-drivers)

PPS needs storage for:

- device public keys
- key sequence counters
- threshold groups
- nonces

Supported drivers:

```
memory
file
pdo
redis

```

### Memory

[](#memory)

For testing only:

```
PPS_STORAGE_DRIVER=memory
```

### File

[](#file)

Good for development or single-process apps:

```
PPS_STORAGE_DRIVER=file
```

Default path:

```
storage/app/pps

```

### PDO

[](#pdo)

Recommended for production:

```
PPS_STORAGE_DRIVER=pdo
PPS_DB_CONNECTION=mysql
```

Then run:

```
php artisan migrate
```

### Redis

[](#redis)

For high-performance distributed deployments:

```
PPS_STORAGE_DRIVER=redis
PPS_REDIS_CONNECTION=default
```

---

Routes
------

[](#routes)

By default, this package registers the following routes:

MethodURIDescriptionGET`/pps/health`Health checkGET`/pps/challenge`Create authentication/registration challengePOST`/pps/register`Register a devicePOST`/pps/verify`Verify a Pulse TokenPOST`/pps/transaction/challenge`Create transaction challengePOST`/pps/transaction/verify`Verify transaction-bound PulseYou can customize the prefix:

```
PPS_ROUTE_PREFIX=pps
```

Or disable default routes:

```
PPS_ROUTES_ENABLED=false
```

---

Health Check
------------

[](#health-check)

```
curl http://localhost:8000/pps/health
```

Example response:

```
{
    "status": "ok",
    "protocol": "PulseProof Sentinel Protocol",
    "version": 1,
    "algorithm": "PPS-ED25519-CBOR30",
    "epoch_seconds": 30,
    "rp_id": "localhost",
    "time": 1769174400,
    "epoch": 58972480
}
```

---

Basic Authentication Flow
-------------------------

[](#basic-authentication-flow)

### 1. Get Challenge

[](#1-get-challenge)

```
curl http://localhost:8000/pps/challenge
```

Example response:

```
{
    "nonce": "base64url-nonce",
    "epoch": 58972480,
    "session_id": "base64url-session",
    "qr_payload": "pulseproof://challenge?..."
}
```

---

### 2. Register Device

[](#2-register-device)

Device registration requires a `registration_token`.

The `registration_token` is generated by a PPS client using the core package:

```
use Pps\Client\RegistrationBuilder;

$builder = new RegistrationBuilder();
$registration = $builder
    ->rpId('localhost')
    ->nonce($nonceFromChallenge)
    ->userHandle('user-123')
    ->deviceName('My Phone')
    ->withDuress(true)
    ->build();

$registrationToken = $registration['token'];
$clientState = $registration['client_state'];
```

Then send it to Laravel:

```
curl -X POST http://localhost:8000/pps/register \
  -H "Content-Type: application/json" \
  -d '{
    "registration_token": "base64url-registration-token",
    "nonce": "base64url-nonce"
  }'
```

Example response:

```
{
    "status": "ok",
    "kid": "base64url-kid"
}
```

---

### 3. Authenticate

[](#3-authenticate)

The client creates a Pulse Token:

```
use Pps\Client\AuthenticatorClient;

$client = new AuthenticatorClient($clientState);

$pulse = $client
    ->rpId('localhost')
    ->nonce($nonceFromChallenge)
    ->createPulse();

$pulseToken = $pulse['token'];
$trustCode = $pulse['trust_code'];
```

Then send it to Laravel:

```
curl -X POST http://localhost:8000/pps/verify \
  -H "Content-Type: application/json" \
  -d '{
    "pulse_token": "base64url-pulse-token",
    "nonce": "base64url-nonce",
    "trust_code": "49371826"
  }'
```

Example response:

```
{
    "status": "ok",
    "mode": "normal"
}
```

---

Facade Usage
------------

[](#facade-usage)

```
use Pps\Laravel\Facades\PulseProof;

$challenge = PulseProof::challenge();

$nonce = $challenge['nonce'];
```

Verify a Pulse:

```
$result = PulseProof::verify(
    pulseToken: $request->input('pulse_token'),
    nonceB64u: $request->input('nonce'),
    trustCode: $request->input('trust_code')
);

if ($result->honey) {
    // Silent duress detected.
    // Return a normal-looking response.
}

if ($result->ok) {
    // Authentication succeeded.
}
```

---

Transaction Signing
-------------------

[](#transaction-signing)

Create a transaction challenge:

```
curl -X POST http://localhost:8000/pps/transaction/challenge \
  -H "Content-Type: application/json" \
  -d '{
    "action": "withdraw",
    "amount_minor": 2500067,
    "currency": "IRR",
    "recipient": "IR820540102680020817909002"
  }'
```

Example response:

```
{
    "nonce": "base64url-nonce",
    "epoch": 58972480,
    "session_id": "base64url-session",
    "tx_hash": "base64url-tx-hash",
    "amount_mark": "67"
}
```

The client should bind the transaction hash and amount to the Pulse:

```
use Pps\Crypto\Base64Url;
use Pps\Payload\ContextObject;

$context = new ContextObject();
$context->sessionId = Base64Url::decode($sessionId);
$context->txHash = Base64Url::decode($txHash);

$pulse = $client
    ->rpId('localhost')
    ->nonce($nonce)
    ->context($context)
    ->amountMinor(2500067)
    ->createPulse();
```

Then verify:

```
curl -X POST http://localhost:8000/pps/transaction/verify \
  -H "Content-Type: application/json" \
  -d '{
    "pulse_token": "base64url-pulse-token",
    "nonce": "base64url-nonce",
    "trust_code": "49371867",
    "action": "withdraw",
    "amount_minor": 2500067,
    "currency": "IRR",
    "recipient": "IR820540102680020817909002",
    "session_id": "base64url-session",
    "tx_hash": "base64url-tx-hash"
  }'
```

The Trust Code includes the AmountMark:

```
Trust Code: 49371867
AmountMark: 67

```

The last two digits match the transaction amount modulo 100.

---

Silent Duress
-------------

[](#silent-duress)

PPS supports silent duress signaling.

If a user authenticates under coercion, the client can sign with a hidden duress key.

The server detects this internally:

```
if ($result->honey) {
    // Outward response must remain normal.
}
```

Important:

> The HTTP response for a duress authentication must be indistinguishable from a normal successful authentication.

Do not return:

```
{
    "status": "duress"
}
```

Instead, return:

```
{
    "status": "ok"
}
```

Then internally:

- restrict account capabilities
- block high-value operations
- delay settlement
- trigger a silent alert
- preserve audit logs

---

Threshold Mode
--------------

[](#threshold-mode)

PPS supports offline multi-device threshold approval.

The core package implements n-of-m Ed25519 multisignature.

This Laravel package can verify threshold Pulses through the same verification engine provided by `pps-protocol/pps-php`.

Threshold group management may be implemented in your application or added in future versions of this package.

---

Artisan Commands
----------------

[](#artisan-commands)

### Install PPS Resources

[](#install-pps-resources)

```
php artisan pps:install
```

Publishes:

```
config/pps.php
database/migrations/*_create_pps_tables.php

```

---

### Generate Key Pair

[](#generate-key-pair)

```
php artisan pps:key-generate
```

Example output:

```
{
    "public_key": "base64url-public-key",
    "secret_key": "base64url-secret-key",
    "seed": "base64url-seed"
}
```

Warning:

> Never commit secret keys to source control.

---

Testing
-------

[](#testing)

Run package tests:

```
composer install
vendor/bin/phpunit
```

---

Package Architecture
--------------------

[](#package-architecture)

```
pps-protocol/pps-php
    Core protocol implementation
    No framework dependency

pps-protocol/laravel-pps
    Laravel bridge
    Depends on pps-protocol/pps-php

```

This package does not reimplement the protocol.

It only provides Laravel integration around the core package.

---

Security
--------

[](#security)

This package is experimental.

It has not been independently audited.

Do not use it in production without:

- cryptographic review
- security audit
- interoperability testing
- operational risk assessment

See [SECURITY.md](SECURITY.md).

---

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md).

---

License
-------

[](#license)

Apache License 2.0

See [LICENSE](LICENSE).

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/38b7c34a3bb546140c926613060af92984bc184c8731e1cf9aaea704ca88a685?d=identicon)[hosseinhezami](/maintainers/hosseinhezami)

---

Top Contributors

[![hosseinhezami](https://avatars.githubusercontent.com/u/8210576?v=4)](https://github.com/hosseinhezami "hosseinhezami (1 commits)")

---

Tags

2faauthenticationcbored25519fido2laravellaravel-packagemfaoffline-authenticationppspulseproofsecurity-protocoltotp-alternativetransaction-signingwebauthnlaravelAuthentication2faEd25519cborFIDO2webauthnMFAtransaction-signingPPStotp-alternativepulseproofsecurity-protocoloffline-authenticationduress

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/pps-protocol-laravel-pps/health.svg)

```
[![Health](https://phpackages.com/badges/pps-protocol-laravel-pps/health.svg)](https://phpackages.com/packages/pps-protocol-laravel-pps)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k30.2M151](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M136](/packages/laravel-pulse)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77922.3M185](/packages/laravel-mcp)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M133](/packages/roots-acorn)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)

PHPackages © 2026

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