This guide explains dynamic policy binding in PulseProof Sentinel Protocol, abbreviated PPS.
Policy binding allows the relying party to require specific security properties for a given authentication or transaction.
Different operations require different security levels.
Examples:
Login:
require biometric
8-digit Trust Code
Withdrawal:
require biometric
require secure enclave
require AmountMark
threshold = 2
Admin action:
require hardware key
threshold = 3
require proximity
PPS allows the server to send a policy object.
The authenticator hashes the policy and binds it to the Pulse.
The server verifies that the Pulse was created under the expected policy.
The PPS policy object is a CBOR map.
Fields:
1: min_trust_digits
2: require_biometric
3: require_secure_enclave
4: threshold
5: max_amount_minor
6: require_proximity
7: max_clock_skew
8: allow_offline
9: require_amount_mark
10: require_duress_support
All fields are optional.
Absent fields mean the policy does not impose that requirement.
Minimum total Trust Code digits.
Example:
{
"1": 8
}
If AmountMark is present, total digits include the two AmountMark digits.
Recommended minimum:
8
For high-risk typed fallback:
10 or 12
Requires user verification with biometrics.
Example:
{
"2": true
}
The authenticator should enforce this locally.
The server may also rely on device attestation if available.
Requires private key operations inside secure hardware.
Example:
{
"3": true
}
Secure hardware may include:
Required number of approving devices.
Example:
{
"4": 2
}
This is relevant for threshold mode.
The server MUST also enforce the stored group threshold.
Do not rely only on the policy object.
Maximum transaction amount in minor units.
Example:
{
"5": 10000000
}
If the transaction amount exceeds this value, the authenticator should reject signing.
The server should also enforce this independently.
Requires proof that authenticator and initiating device are close.
Example:
{
"6": true
}
Proximity proof may use:
Proximity proofs are heuristic, not absolute.
Maximum allowed clock skew in epochs.
Example:
{
"7": 1
}
Default recommendation:
1
Larger values reduce security.
Indicates whether offline Pulses are allowed.
Example:
{
"8": true
}
If false, the server should reject Pulses without a valid nonce.
Requires AmountMark in Trust Code and Pulse.
Example:
{
"9": true
}
Useful for transaction signing.
Indicates the authenticator should support duress signaling.
Example:
{
"10": true
}
This does not force the user to use duress.
It indicates the deployment expects duress capability.
The policy object is encoded using deterministic CBOR.
pol = SHA256(cbor(policy_object))
The Pulse payload includes:
13: pol
The server compares this hash with the expected policy hash.
1. RP decides required policy for the operation.
2. RP encodes policy object.
3. RP sends policy to authenticator.
- QR code
- deep link
- SDK challenge
- API response
4. Authenticator displays policy-relevant details.
5. Authenticator hashes policy.
6. Authenticator includes pol in Pulse.
7. RP verifies pol matches expected policy.
{
"1": 8,
"2": true,
"8": true
}
Meaning:
{
"1": 8,
"2": true,
"3": true,
"8": false
}
Meaning:
{
"1": 8,
"2": true,
"3": true,
"4": 2,
"5": 10000000,
"6": true,
"9": true
}
Meaning:
{
"1": 10,
"2": true,
"3": true,
"4": 3,
"6": true,
"8": false
}
Meaning:
{
"1": 10,
"7": 2,
"8": true
}
Meaning:
Policy binding prevents simple downgrade attacks.
If an attacker removes or weakens policy fields, the policy hash changes.
The server MUST reject Pulses with unexpected policy hashes.
The server SHOULD NOT accept a weaker policy than required.
Example:
Expected policy hash: A
Pulse policy hash: B
Result: reject
The server is ultimately responsible for enforcement.
Even if the authenticator enforces policy, the server MUST verify:
Do not trust the client alone.
When receiving a policy, the authenticator should:
Example user screen:
High-value approval required
Requirements:
Biometric: required
Secure enclave: required
Devices: 2
Maximum amount: 10,000,000
Proximity: required
Amount: 2,500,067 IRR
Trust Code: 49371867
[Reject] [Approve]
Servers can choose policies dynamically based on risk.
Risk signals:
Example:
Low risk:
single device
8-digit Trust Code
Medium risk:
single device
biometric required
secure enclave required
High risk:
threshold = 2
proximity required
AmountMark required
Very high risk:
threshold = 3
no offline fallback
manual review
Policy objects may reveal internal risk logic.
This is usually acceptable, but consider:
If custom policy fields are needed, define them carefully and canonically.
If policy semantics change, use a new policy version or new field labels.
Do not silently reinterpret existing fields.
This avoids ambiguous verification.
Avoid:
Policy binding allows PPS to support flexible, risk-adaptive security requirements.
The policy object is hashed and bound to the Pulse.
The server verifies the hash and independently enforces the requirements.
Policy binding is one of the main mechanisms that makes PPS suitable for transaction signing and high-security flows.