This guide describes how to deploy PulseProof Sentinel Protocol, abbreviated PPS, in a realistic service environment.
PPS is experimental. Do not use it in production without security review.
A PPS deployment should provide:
+----------------+
| User Device |
| Authenticator |
+-------+--------+
|
| QR / Deep Link / API
v
+----------------+ +------------------+
| Web/Mobile App |<------>| Relying Party |
+----------------+ | Backend |
+--------+---------+
|
+-----------------+-----------------+
| | |
+------v-----+ +------v-----+ +------v-----+
| Nonce | | PPS State | | Audit Log |
| Store | | Database | | Store |
+------------+ +------------+ +------------+
Handles:
Handles:
Handles:
Handles:
Handles:
This is an example schema. Adapt it to your database.
CREATE TABLE pps_devices (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT UNSIGNED NOT NULL,
kid VARCHAR(128) NOT NULL,
current_pk VARCHAR(64) NOT NULL,
key_seq BIGINT UNSIGNED NOT NULL DEFAULT 0,
last_ctr BIGINT UNSIGNED NOT NULL DEFAULT 0,
duress_pk VARCHAR(64) NULL,
duress_key_seq BIGINT UNSIGNED NOT NULL DEFAULT 0,
duress_last_ctr BIGINT UNSIGNED NOT NULL DEFAULT 0,
revoked TINYINT(1) NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
UNIQUE KEY unique_kid (kid),
INDEX idx_user (user_id)
);
CREATE TABLE pps_nonces (
nonce VARCHAR(128) PRIMARY KEY,
session_id VARCHAR(128) NOT NULL,
user_id BIGINT UNSIGNED NULL,
purpose VARCHAR(32) NOT NULL,
created_at DATETIME NOT NULL,
expires_at DATETIME NOT NULL,
used TINYINT(1) NOT NULL DEFAULT 0,
INDEX idx_session (session_id)
);
CREATE TABLE pps_threshold_groups (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
gid VARCHAR(128) NOT NULL,
user_id BIGINT UNSIGNED NOT NULL,
rp_hash VARCHAR(64) NOT NULL,
threshold TINYINT UNSIGNED NOT NULL,
last_ctr BIGINT UNSIGNED NOT NULL DEFAULT 0,
revoked TINYINT(1) NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
UNIQUE KEY unique_gid (gid),
INDEX idx_user (user_id)
);
CREATE TABLE pps_threshold_signers (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
gid VARCHAR(128) NOT NULL,
kid VARCHAR(128) NOT NULL,
public_key VARCHAR(64) NOT NULL,
revoked TINYINT(1) NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL,
UNIQUE KEY unique_gid_kid (gid, kid)
);
CREATE TABLE pps_duress_events (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT UNSIGNED NOT NULL,
kid VARCHAR(128) NOT NULL,
session_id VARCHAR(128) NULL,
ip VARCHAR(45) NULL,
user_agent TEXT NULL,
created_at DATETIME NOT NULL,
handled TINYINT(1) NOT NULL DEFAULT 0,
INDEX idx_user (user_id)
);
Nonces MUST be:
Recommended lifetime:
60 seconds
Recommended storage:
Redis or database with TTL
Example nonce record:
{
"nonce": "base64url",
"session_id": "base64url",
"purpose": "login",
"expires_at": "2026-07-23T12:01:00Z",
"used": false
}
Mark nonce used only after successful verification.
PPS state updates must be atomic.
Use database transactions and row locks.
Example:
SELECT * FROM pps_devices
WHERE kid = ?
FOR UPDATE;
Then verify and update:
UPDATE pps_devices
SET current_pk = ?,
key_seq = ?,
last_ctr = ?,
updated_at = NOW()
WHERE kid = ?;
Never update counters before signature verification.
Rate limiting is mandatory for safe deployment.
Recommended limits:
5 failed attempts per account per 15 minutes
20 failed attempts per IP per hour
1 Trust Code attempt per session per 30 seconds
For Trust Code fallback:
8-digit code: strict rate limiting required
10-digit code: recommended
12-digit code: preferred
Use exponential backoff for repeated failures.
Log the following events:
Avoid logging:
Alert on:
Duress alerts should be routed to a trained security response team.
When a Honey-Pulse is detected:
Example outward response:
{
"status": "ok"
}
Internal state:
{
"risk_level": "duress",
"account_mode": "restricted",
"alert": "silent"
}
A practical migration path:
Keep TOTP enabled.
Allow users to register PPS devices.
Show security benefits.
Offer PPS for high-value actions.
Require PPS for sensitive operations.
Keep TOTP fallback for low-risk actions.
Remove TOTP for users with PPS devices.
Provide recovery options.
Users may lose devices.
Recovery options:
Recovery must be protected against social engineering.
Devices should support periodic key rotation.
Rotation flow:
1. Authenticate with existing trusted device.
2. Generate new key pair.
3. Register new public key.
4. Revoke old key if appropriate.
PPS ratcheting provides automatic per-Pulse rotation in single-device mode.
For production systems:
Recommended privacy practices:
kid values per RPkidDepending on jurisdiction and industry, consider:
PPS does not automatically satisfy any compliance regime.
Before production deployment: