---
icon: shield-lock
label: Security
order: 800
expanded: false
---

This section describes the two security mechanisms most relevant to integrations:

1. **Incoming signed verification URL** (request integrity)
2. **Outgoing signed result URL** (result integrity)

These are independent features and can be enabled/used separately.

### Incoming signed verification URL (request integrity)

This is the **recommended default** for all projects. The `ForceSignedInput` verification configuration setting is **enabled by default** — disabling it is only acceptable for local testing.

Some projects may require that the initial verification URL (the one your application sends the user to) is **signed**.

Purpose:

- prevent unauthorized tampering with query parameters before the verification starts
- ensure the verification session is initiated with an authentic, unmodified set of inputs

Integration guidance:

- treat the signing key as a secret
- sign URLs on a trusted system (typically your backend)
- do not generate signatures in browser JavaScript

If your project requires signed input and the signature is missing/invalid, the verification will be rejected.

#### Best practice: short-lived, single-use links

For maximum security we recommend issuing a **fresh signed URL for every session**, with both an expiration (`reExpiration`) and a one-time-use nonce (`reNonce`). The signature creation endpoint applies safe defaults out of the box:

- **Expiration is enabled by default** (1 day lifetime). Calling the create-signature endpoint with no `SecuritySettings` produces a URL that expires in 24 hours.
- `ExpirationEnabled` adds `reExpiration` to the URL. The link is rejected with `410 Gone` after the timestamp passes. The lifetime is controlled by `ExpirationInSeconds` — **default `86400` (1 day), maximum `604800` (7 days)**.
- `EnableNonce` adds `reNonce` to the URL (opt-in). The first successful session consumes the nonce; subsequent attempts to open the same URL are rejected with `410 Gone`.

If your integration genuinely needs a **reusable link** (for example a verification URL embedded in an email that the user opens days later), send `{ "expirationEnabled": false }` and omit the nonce.

!!!warning Nonce requires expiration
When `EnableNonce` is `true`, expiration must remain enabled (which is the default). Sending `{ "enableNonce": true, "expirationEnabled": false }` is rejected with `400 Bad Request`.
!!!

When the URL is opened, the service validates in this order: signature, expiration, nonce. The nonce is only consumed if the signature is valid and the link has not expired, so a forged or stale URL never burns a legitimate nonce.

The same checks are also exposed by the `POST /v1/signature/validate` endpoint (read-only), so your backend can detect an expired or already-used link before redirecting the user. Validating via this endpoint **does not** consume the nonce.

### Outgoing signature on the result URL (result integrity)

The result redirect includes `reSignature`, which can be used for tamper detection.

- Signature validation is **optional**.
- If you need higher assurance, validate `reSignature` on your backend before trusting any other parameters.

Operational recommendations:

- consider all query parameters untrusted until signature verification passes
- validate on your backend (or another trusted environment)
- if verification fails, do not trust or persist the reported outcome

### Origin validation (for iFrame / Popup window)

In embedded scenarios, the VerifEye result page posts a message to the parent/opener.

Recommendations:

- always validate `event.origin` against the expected VerifEye domain(s)
- treat `event.data.redirectedTo` as untrusted input until you validate the URL with `reSignature` checking

---

*Last updated: 2026-02-03*

