# WPsigner Security & Compliance Pack

> Roles, signer gates, Digital ID, timestamping, audit trails, encryption, and storage retention.

Generated for AI assistants from the official WPsigner docs.
HTML guide: https://docs.wpsigner.com/support/use-with-ai/
Pages in this pack: 12

## Suggested prompt

```text
You are helping me configure and use WPsigner, a self-hosted electronic-signature plugin for WordPress.
Use ONLY the documentation below as your source of truth.
Each page header includes edition: lite, pro, or both. Never invent Pro-only features for Lite.
If something is not covered, say so clearly and ask for the missing detail.
Prefer exact admin menu paths, shortcodes, endpoints, and settings names from the docs.
```

## Contents

1. [Legal Compliance](https://docs.wpsigner.com/md/compliance.md) — https://docs.wpsigner.com/compliance/
2. [Client Portal](https://docs.wpsigner.com/md/core-features/client-portal.md) — https://docs.wpsigner.com/core-features/client-portal/
3. [Security & Compliance](https://docs.wpsigner.com/md/core-features/security-compliance.md) — https://docs.wpsigner.com/core-features/security-compliance/
4. [Team Roles & Permissions](https://docs.wpsigner.com/md/core-features/team-roles.md) — https://docs.wpsigner.com/core-features/team-roles/
5. [Digital Identity & Security](https://docs.wpsigner.com/md/digital-identity.md) — https://docs.wpsigner.com/digital-identity/
6. [Audit Trails](https://docs.wpsigner.com/md/digital-identity/audit-trails.md) — https://docs.wpsigner.com/digital-identity/audit-trails/
7. [Digital ID (PKI Certificates)](https://docs.wpsigner.com/md/digital-identity/digital-id.md) — https://docs.wpsigner.com/digital-identity/digital-id/
8. [Document Encryption](https://docs.wpsigner.com/md/digital-identity/encryption.md) — https://docs.wpsigner.com/digital-identity/encryption/
9. [Timestamping (TSA)](https://docs.wpsigner.com/md/digital-identity/timestamping.md) — https://docs.wpsigner.com/digital-identity/timestamping/
10. [System Status, Storage & Retention](https://docs.wpsigner.com/md/getting-started/system-status-and-storage.md) — https://docs.wpsigner.com/getting-started/system-status-and-storage/
11. [Didit.me — Identity Verification (KYC)](https://docs.wpsigner.com/md/integrations/didit.md) — https://docs.wpsigner.com/integrations/didit/
12. [Report a Security Issue](https://docs.wpsigner.com/md/support/security.md) — https://docs.wpsigner.com/support/security/

---

# Legal Compliance

> Complete guide to electronic signature laws, regulations, and compliance standards for ESIGN, UETA, eIDAS, HIPAA, and more.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/compliance/
Markdown: https://docs.wpsigner.com/md/compliance.md

WPsigner provides technical controls that can support an electronic-signature compliance program. This page summarizes major frameworks and maps relevant WPsigner features; it is not a certification that every installation or transaction is compliant.

## Electronic Signature Laws

### United States

#### ESIGN Act (2000)

The **Electronic Signatures in Global and National Commerce Act** establishes that:

| Requirement | Meaning |
|-------------|---------|
| Legal equivalence | E-signatures have same legal weight as handwritten |
| Intent | Signer must intend to sign |
| Consent | Parties must agree to use electronic format |
| Record retention | E-records must be accurately retained |

**Relevant WPsigner controls:**
- Signing actions and consent records
- Audit trails and retained document records
- Identity and access gates when configured

#### UETA (1999)

The **Uniform Electronic Transactions Act** is adopted by 49 states (all except New York, which has similar laws):

| Principle | WPsigner Support |
|-----------|------------------|
| E-signature validity | Signature workflow and consent evidence |
| E-record validity | PDF storage with audit trail |
| Attribution | Email, access, optional OTP/KYC, and audit evidence |
| Effect of change | Hashing and optional certificate signature help detect changes |

### European Union

#### eIDAS Regulation (2014/910)

The EU's **electronic IDentification, Authentication and trust Services** regulation defines three signature levels:

| Level | Description | Legal Effect | WPsigner |
|-------|-------------|--------------|----------|
| **SES** (Simple) | Any electronic signature | Valid, may need additional evidence | Basic WPsigner workflows can produce SES evidence |
| **AdES** (Advanced) | Uniquely linked to signer and capable of identifying them, under their control, with change detection | Stronger evidence | WPsigner controls can contribute; all legal criteria must still be met |
| **QES** (Qualified) | AdES + qualified certificate + qualified creation process/provider | Equivalent to handwritten across the EU | Requires a QTSP and qualified process outside a normal plugin configuration |

**Configuration orientation (not certification):**

```
┌─────────────────────────────────────────────────────────┐
│ QES (Qualified)                                         │
│ • Qualified certificate and process from a QTSP         │
│ • Cannot be established by an AATL certificate alone    │
├─────────────────────────────────────────────────────────┤
│ AdES-oriented controls                                  │
│ • Strong signer identification and control              │
│ • Unique linkage plus change detection                  │
│ • Must satisfy every eIDAS criterion                    │
├─────────────────────────────────────────────────────────┤
│ SES-oriented workflow                                   │
│ • Basic WPsigner signatures                             │
│ • Audit trail with IP and device info                   │
└─────────────────────────────────────────────────────────┘
```

### Other Regions

| Country/Region | Law | Status |
|----------------|-----|--------|
| **United Kingdom** | UK eIDAS / ECA 2000 | ✅ Recognized |
| **Canada** | PIPEDA + Provincial | ✅ Recognized |
| **Australia** | Electronic Transactions Act 1999 | ✅ Recognized |
| **India** | IT Act 2000 | ✅ Recognized |
| **Brazil** | MP 2.200-2/2001 | ✅ Recognized |

---

## Industry Regulations

### Healthcare (HIPAA)

The **Health Insurance Portability and Accountability Act** applies to Protected Health Information (PHI):

| HIPAA Requirement | WPsigner Solution |
|-------------------|-------------------|
| Access controls | Role-based WordPress permissions |
| Audit controls | Complete audit trail logging |
| Integrity controls | Digital signatures detect tampering |
| Transmission security | HTTPS encryption (your server) |
| Business Associate Agreement | Required with hosting provider |

**HIPAA Compliance Checklist:**
- [ ] Host on HIPAA-compliant infrastructure
- [ ] Configure OTP verification
- [ ] Enable Digital ID signing
- [ ] Enable audit trail with geolocation
- [ ] Sign BAA with hosting provider
- [ ] Implement access controls
- [ ] Train staff on procedures

> **important**
WPsigner provides technical controls. You are responsible for administrative and physical safeguards and, where required, appropriate agreements with hosting and service providers.

### Financial Services (SOX, FINRA)

| Requirement | WPsigner Feature |
|-------------|------------------|
| **SOX 802** - Record retention | Permanent document storage |
| **SOX 802** - Integrity | Digital signatures, tampering detection |
| **FINRA 4511** - Books and records | Timestamped audit trails |
| **FINRA 3110** - Supervision | Audit logs show who signed what |

### Legal (ABA Guidelines)

The American Bar Association recognizes e-signatures for:
- Client engagement letters
- Contracts and agreements
- Settlement agreements
- Non-disclosure agreements

**Best practices for legal documents:**
1. Enable Digital ID (PKI certificate)
2. Enable timestamping (TSA)
3. Use sequential signing for approval chains
4. Keep complete audit trails

### Real Estate (RESPA, TRID)

Many real estate documents can be signed electronically:

| ✅ Allowed | ⚠️ May Require Wet Signature |
|-----------|------------------------------|
| Purchase agreements | Deeds (varies by state) |
| Listing agreements | Notarized documents |
| Lease agreements | Some title documents |
| Addendums | |

---

## Key Compliance Features

### 1. Digital Signatures (PKI)

Cryptographic signatures that prove:
- **Authenticity** - Who signed
- **Integrity** - Document not altered
- **Non-repudiation** - Signer cannot deny signing

Configure at: **WPsigner → More → Digital ID**

### 2. Timestamping (TSA)

RFC 3161 timestamps prove:
- **Exact signing time** - From trusted third party
- **Long-term validity** - Valid after certificate expires

Configure at: **WPsigner → Settings → Legal & Privacy**

### 3. Audit Trails

Every document includes:
- All signer actions with timestamps
- IP addresses and device information
- Consent records
- Viewing history

See: [Audit Trails Documentation](/digital-identity/audit-trails/)

### 4. Identity Verification

Multiple verification methods:
- **Email verification** - Link only works for recipient
- **OTP verification** - Code sent to signer's email
- **PIN protection** - Additional access code

### 5. Certificate of Completion

Every completed document includes:
- Summary of all signatures
- Complete audit trail
- Compliance attestation

---

## Signature Validity by Document Type

### Generally Accepted

| Document Type | Notes |
|---------------|-------|
| Contracts | All jurisdictions |
| NDAs | All jurisdictions |
| Employment agreements | All jurisdictions |
| Service agreements | All jurisdictions |
| Purchase orders | All jurisdictions |
| Terms and conditions | All jurisdictions |
| Client proposals | All jurisdictions |
| HR documents | Most jurisdictions |

### May Require Special Handling

| Document Type | Consideration |
|---------------|---------------|
| Real estate deeds | Check state requirements |
| Wills and testaments | Often require witnesses/notarization |
| Court documents | Check local rules |
| Powers of attorney | Varies by jurisdiction |
| Healthcare directives | May require witnesses |

### Typically Require Wet Signature

| Document Type | Reason |
|---------------|--------|
| Notarized documents | Physical notary required |
| Some government forms | Specific requirements |
| Certain immigration forms | Federal requirements |

---

## Compliance Checklist

### Basic Compliance (SES)

- [x] WPsigner installed and configured
- [x] HTTPS enabled on your site
- [x] Audit trail enabled (default)
- [x] Documents stored securely
- [x] Access controls in place

### Enhanced Compliance (AdES)

- [ ] Digital ID configured
- [ ] OTP verification enabled
- [ ] Timestamping enabled
- [ ] Advanced audit trail (geolocation, device)
- [ ] Document retention policy defined

### Maximum Compliance (QES-ready)

- [ ] All AdES requirements
- [ ] Commercial AATL certificate from QTSP
- [ ] Identity verification procedures
- [ ] Staff training documented
- [ ] Compliance policies written

---

## Compliance Score

WPsigner displays a Compliance Score in **More → Security & Compliance**:

| Score | Level | Features Enabled |
|-------|-------|------------------|
| **Basic (SES)** | Simple Electronic Signature | Default configuration |
| **Enhanced (SES+)** | Enhanced Simple | + Identity verification |
| **Advanced (AdES)** | Advanced Electronic Signature | + Digital ID + TSA + OTP |

---

## Legal Disclaimer

> **caution**
This documentation provides general information about electronic signature laws and is not legal advice. Laws vary by jurisdiction and change over time. Consult with a qualified attorney for requirements applicable to your situation.

WPsigner provides technical tools for compliance. You are responsible for:
- Understanding applicable regulations
- Configuring appropriate security settings
- Implementing proper procedures
- Training your staff
- Maintaining documentation

---

## Next Steps

- [Digital ID Configuration](/digital-identity/digital-id/) - Set up PKI certificates
- [Timestamping](/digital-identity/timestamping/) - Enable RFC 3161 timestamps
- [Audit Trails](/digital-identity/audit-trails/) - Understanding the legal record
- [FAQ](/support/faq/) - Common compliance questions

---

# Client Portal

> Complete guide to setting up and using the WPsigner Client Portal — public-facing dashboards for administrators and signers to manage contracts.

edition: pro
Edition: Pro
AI note: This page requires WPsigner Pro. Do not tell Lite users they already have this feature.
HTML: https://docs.wpsigner.com/core-features/client-portal/
Markdown: https://docs.wpsigner.com/md/core-features/client-portal.md

The **Client Portal** lets you create public-facing dashboards where your team and your signers can view and manage contracts directly on your WordPress site — no admin access needed.

> **Requires WPsigner Pro**
Client Portal shortcodes are not included in **Lite**. [Upgrade to Pro](https://wpsigner.com/pricing/?utm_source=docs&utm_medium=upgrade&utm_campaign=client-portal) · [Lite vs Pro](/getting-started/lite-vs-pro/)

There are two portals:

| Portal | Shortcode | Who uses it |
|--------|-----------|-------------|
| **Admin Portal** | `[insigner_admin_portal]` | Your team (admins, managers, senders, viewers) |
| **Signer Portal** | `[insigner_client_portal]` | External signers who need to check their documents |

---

## Enabling the Portal

1. Go to **WPsigner → Appearance → Client Portal** in the WordPress admin
2. Under **Portal Status**, check **Enable Client Portal**
3. Click **Save Changes**

> **tip**
The shortcodes won't render anything until you enable the portal in Appearance → Client Portal.

---

## Login Mode

Choose how users authenticate when accessing the portal:

| Mode | Behavior |
|------|----------|
| **WordPress Login** | Redirects to `wp-login.php`. Best if users already have WP accounts. |
| **Custom Login Page** | Shows a branded login form directly on the portal page. Best for a seamless, white-label experience. |

### Setting Up Custom Login

1. In **WPsigner → Appearance → Client Portal**, set **Login Mode** to **Custom Login Page**
2. A **page selector** dropdown appears — choose the WordPress page where you placed the portal shortcode
3. Save. Non-logged-in visitors will see a branded login form on that page

The custom login form includes:
- Your **portal logo** (or company logo / brand initials as fallback)
- **Rate limiting** — blocks IP after 5 failed attempts for 15 minutes
- **Forgot Password** link that goes to WordPress password recovery

---

## Setting Up the Admin Portal

The Admin Portal gives your team a complete dashboard to view, search, and manage all contracts.

### Step 1: Create the Page

1. Go to **Pages → Add New** in WordPress
2. Give it a title (e.g., "Document Portal" or "Admin Dashboard")
3. Add the shortcode:

```
[insigner_admin_portal]
```

4. Publish the page

### Step 2: Configure Permissions

Users see contracts based on their **WPsigner role**:

| Role | Can see |
|------|---------|
| **Administrator** | All contracts from all users |
| **WPsigner Admin** | All contracts from all users |
| **Manager** | All contracts; can manage documents created by other users |
| **Sender** | Only their own contracts |
| **Viewer** | All contracts (read-only for documents created by other users) |

> **important**
Users must have a WordPress account with a WPsigner role to access the Admin Portal. Users without a WPsigner role will see an "Access Denied" message. See [Team Roles & Permissions](/core-features/team-roles/) for the complete capability matrix.

### What's Included in the Admin Portal

**Stats Bar** — Five cards at the top showing:
- Total contracts
- Signed / Completed
- Pending
- Declined
- Expired

**Contract Table** — A paginated, searchable table with:
- Document title
- Creation date
- Signers (with progress)
- Status badge
- Action buttons (View Details, Download PDF, View Certificate)

**Date Filter** — Two date pickers to filter contracts by date range.

**Search** — Real-time search by document title.

**Status Tabs** — Filter by status: All, Signed, Pending, Declined.

**Weekly Overview Chart** — A bar chart showing the last 7 days of document activity (signed, sent, completed, declined).

**Recent Activity Feed** — A live feed of the latest actions across all documents.

**Detail Modal** — Click any contract for a detailed view with:
- Document metadata
- Signer list with individual statuses
- Full audit trail
- Download/action buttons

---

## Setting Up the Signer Portal

The Signer Portal gives external signers a simple view of all documents they've been asked to sign.

### Step 1: Create the Page

1. Go to **Pages → Add New** in WordPress
2. Give it a title (e.g., "My Contracts" or "Signer Portal")
3. Add the shortcode:

```
[insigner_client_portal]
```

4. Publish the page

### Step 2: Create WP Accounts for Signers

Signers need a WordPress account with an email address matching the signer email on their documents. When they log in, the portal shows all contracts linked to their email.

> **note**
You don't need to assign a WPsigner role to signers. Any WordPress user can access the Signer Portal — it matches by email.

### What's Included in the Signer Portal

**Stats Bar** — Three cards:
- Total documents
- Signed
- Pending

**Contract Table** — Lists all their documents with:
- Document title
- Date received
- Signer status (Pending / Signed / Declined)
- Action buttons

**Available Actions:**

| Action | When |
|--------|------|
| **Sign Now** | When signer status is pending – goes directly to the signing page |
| **Download PDF** | When document is completed |
| **View Certificate** | When audit certificate is available |
| **View Details** | Always – shows document info and signer list |

---

## Branding & Customization

All portal appearance settings are managed from **WPsigner → Appearance → Client Portal**.

### Portal Logo

Upload a **specific logo for the portal**, separate from your main company logo in Appearance → Brand.

- If a portal logo is set, it appears in the **portal header** and **login screen**
- If no portal logo is set, the **company logo** from Appearance → Brand is used as fallback
- If neither is set, the **brand initials** are shown in a colored badge
- Recommended: max 200px wide, transparent background

### Welcome Text

Set a **custom greeting message** shown on the portal dashboard. Logged-in users see:

> **Hello, [User Name]**  
> Your custom welcome text here.

Max 500 characters. Leave empty to show only the greeting without extra text.

### Primary Color

Your main brand color. Used for:
- Buttons and active states
- Tab indicators
- Stat card icons
- Activity chart bars
- Login form accents
- Portal header accent

### Accent Color

A secondary color used for:
- Status badges (e.g., Signed)
- Visual accents and highlights
- Chart elements

Both colors include a **live preview** in the admin panel so you can see how they look before saving.

### Custom CSS

For advanced customization, you can add your own CSS rules to further style the portal.

```css
/* Example: change stat card background */
.wps-portal-stat-card {
    background: #f8f9fa;
}

/* Example: rounded contract table */
.wps-portal-table {
    border-radius: 16px;
}
```

- Max 5,000 characters
- HTML tags are automatically stripped
- Dangerous patterns (`@import`, `url()`, `expression()`, etc.) are blocked for security

> **caution**
Incorrect CSS may break the portal layout. Test your styles carefully.

### Company Branding (Fallback)

The portal automatically uses your **Company Name** from WPsigner's general settings (**WPsigner → Settings**). The brand name appears in the portal header alongside the logo.

---

## Responsive / Mobile Support

The Client Portal is fully responsive:

| Viewport | Layout |
|----------|--------|
| **Desktop** (1024px+) | Full grid: table + activity sidebar |
| **Tablet** (768px) | Single column, stats in 3-col grid, table stacked as cards |
| **Mobile** (480px) | Stats 2-col, compact tabs, fullscreen modal, brand name hidden |

No configuration needed — the layout adapts automatically.

---

## Shortcode Reference

| Shortcode | Portal | Required Role |
|-----------|--------|---------------|
| `[insigner_admin_portal]` | Team dashboard | Any WPsigner role |
| `[insigner_client_portal]` | Signer dashboard | Any WP user (matched by email) |

You can place these shortcodes on any WordPress page. Both portals can coexist on separate pages.

> **caution**
Do not place both shortcodes on the same page. Each portal should have its own dedicated page.

---

## Security

The Client Portal includes multiple layers of security:

- **Role-based access** — Senders are scoped to their own documents; Viewers, Managers, and Admins can view all documents
- **Nonce verification** — Every AJAX request is verified with WordPress nonces
- **Rate limiting** — Custom login blocks brute-force attempts
- **Input sanitization** — All user inputs are sanitized server-side
- **Output escaping** — All data is escaped before rendering
- **Security headers** — `X-Frame-Options` and `X-Content-Type-Options` are set on portal pages
- **Separate nonces** — Each action (login, logout, download, admin, signer) uses its own nonce

---

## Troubleshooting

### "Access Denied" page

The user doesn't have the required WPsigner role. Go to **WPsigner → Users** and assign them a role.

### "Portal not showing"

1. Make sure **Enable Client Portal** is checked in **Appearance → Client Portal**
2. Verify the shortcode is on a published page
3. Clear any caching plugins

### "Login form not appearing"

Check that **Login Mode** is set to **Custom Login Page** and a page is selected in the dropdown.

### "Signer sees no documents"

The signer's WordPress email must match the email used when adding them as a signer. Check both emails match exactly.

### "Stats show 0 for everything"

The user may not have any documents yet. Senders only see documents they created; Viewers, Managers, WPsigner Admins, and WordPress Administrators can view all documents.

---

## Next Steps

- [Creating Documents](/core-features/creating-documents/) — Learn how to create and send documents
- [Signer Workflows](/core-features/signer-workflows/) — Understand sequential vs parallel signing
- [Appearance](/customization/appearance/) — Portal tab plus Brand and Signing Page
- [Email Templates](/customization/email-templates/) — Customize the emails signers receive

---

# Security & Compliance

> Configure signer verification gates, evidence capture, certificates, and timestamping policies in WPsigner.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/core-features/security-compliance/
Markdown: https://docs.wpsigner.com/md/core-features/security-compliance.md

The **Security & Compliance** screen centralizes WPsigner's signing gates and evidence settings. Use it to decide when signers must verify an email, complete KYC, enter an access code, and which cryptographic evidence is added to completed documents. A separate per-signer option can also require a matching WordPress login before the signing page opens.

> **Lite limits**
**Lite** includes email OTP, access codes, audit trail, and local timestamps. KYC integrations, extra OTP channels, and external TSA are **Pro**. [Lite vs Pro](/getting-started/lite-vs-pro/)

Open **WPsigner → More → Security & Compliance**.

> **caution**
These controls strengthen authentication and evidence. They do not by themselves certify a signature as qualified, guarantee compliance, or replace legal advice for your jurisdiction and use case.

## Signing gate policies

OTP, KYC, and access codes each support three policies:

| Policy | Behavior |
|--------|----------|
| **Always** | Require the gate for every applicable signing request |
| **Per document** | Require it only when enabled in that document's Review step |
| **Off** | Do not apply the gate |

With **Per document**, review each document before sending and enable only the controls required for that transaction.

## Email verification (OTP)

OTP verifies that the signer can receive a one-time code through a configured channel.

| Method | Requirement |
|--------|-------------|
| **Email** | Working WordPress email delivery |
| **SMS** | Configured Twilio integration |
| **Both** | Email delivery and Twilio |

Test email and SMS delivery before requiring OTP in production. A failed delivery can prevent the signer from continuing.

WPsigner rate-limits OTP requests and verifies them through protected AJAX actions. If a firewall plugin blocks OTP, check [System Status](/getting-started/system-status-and-storage/) and allowlist the WPsigner actions it reports.

## Identity verification (KYC)

KYC uses the [Didit.me integration](/integrations/didit/) to verify a government-issued ID, selfie match, and liveness result before signing.

1. Configure and test Didit under **WPsigner → More → Integrations → Didit**.
2. Return to **Security & Compliance**.
3. Choose **Always**, **Per document**, or **Off**.

The KYC policy is unavailable or ineffective until Didit credentials are configured. WPsigner stores verification status and decision metadata; identity images remain with Didit.

## Access codes

An access code is a six-digit secret associated with the signing request. The stored code is hashed rather than saved in readable form.

When access codes are required:

1. WPsigner generates or accepts the document's code.
2. Choose whether WPsigner should email the code to signers.
3. The signer must enter the code before continuing.

For stronger separation, deliver the signing link and access code through different channels.

## WordPress login (per signer)

This gate is **opt-in per signer** and **off by default**. It is not a global Security & Compliance policy and it does not replace OTP, KYC, or access codes.

When **Require WordPress login with this email** is checked on a signer:

1. The visitor must be logged in to WordPress.
2. The logged-in account email must match that signer's email (case-insensitive).
3. The unique signing link is not enough on its own.

If nobody is logged in, the signing page asks them to log in and then returns to the same link. If they are logged in with a different account, they see that mismatch and can log out, then log in as the matching user.

Use this when the signer already has a WordPress account on your site (members, staff, LMS users). The checkbox is refused if that email is not a WordPress user — create the account first, or leave the option off. Leave it off for guests and external counterparties. Public campaign links and Bulk Send CSV rows do not use this gate — those flows have no preassigned WordPress user.

You cannot activate a public campaign on a document that already has a gated signer, and you cannot turn the checkbox on while that document has an active campaign. If someone still reaches a public link and types a gated signer's email, WPsigner re-checks the login requirement and refuses the signature until the matching WordPress account is signed in. Individual signing links for a gated signer are never redirected to the campaign URL.

The invitation email adds a short note when the flag is on. Customized email templates need the `require_wp_login` variable if you want that sentence in your own copy.

## Evidence capture

| Control | Evidence added |
|---------|----------------|
| **Capture geolocation** | Approximate signer location when permission and browser support allow |
| **Capture device information** | Browser/device metadata in the audit record |
| **Digital ID (PKI)** | Cryptographic PDF certificate signature |
| **Timestamp provider (TSA)** | Trusted time evidence for the document hash |
| **Immutable timestamping** | Additional configured timestamp evidence |

Geolocation may be unavailable when the signer denies permission, the browser blocks it, or the network obscures the location.

## Compliance score

The screen displays an orientation score based on selected controls:

| Factor | Maximum contribution |
|--------|----------------------|
| OTP policy | 25 |
| Geolocation | 10 |
| Device information | 5 |
| Custom Digital ID certificate | 10 |
| Timestamp provider | Up to 50 |

KYC and access codes are important gates but do not currently add points to this score.

| Displayed level | Score / conditions |
|-----------------|--------------------|
| **SES** | 0–39 |
| **SES+** | 40–64 |
| **AdES** | 65–79 |
| **HA (QES-oriented)** | 80+ plus an active PKI certificate and qualified/custom TSA |

> **important**
The score is configuration guidance, not a legal classification or QES certification. A true Qualified Electronic Signature depends on regulated identity, certificate, provider, and jurisdictional requirements outside a score.

## Recommended profiles

### Routine internal acknowledgement

- OTP: **Per document**
- KYC: **Off**
- Access code: **Off** or **Per document**
- Device information: On
- Geolocation: Based on privacy policy
- Audit trail and secure backups: On

### Higher-risk external agreement

- OTP: **Always**
- KYC: **Per document** or **Always**
- Access code: **Per document**
- Device and geolocation evidence: On where lawful
- Commercial certificate and reliable TSA

Document the reason for each control and avoid collecting more personal data than necessary.

## Before enabling a gate globally

1. Send a test document to accounts you control.
2. Test on desktop and mobile.
3. Confirm SMTP, Twilio, Didit, and TSA connectivity as applicable.
4. Verify the final PDF and audit trail.
5. Publish signer-facing privacy and support instructions.
6. Define retention and deletion policies for collected data.

## Troubleshooting

### KYC cannot be enabled

Configure and test Didit first. The KYC gate only operates when the integration is available.

### SMS is unavailable

Install and configure the WPsigner Twilio integration, then reload the Security & Compliance screen.

### OTP requests fail

Check SMTP, spam filtering, caching, and security-plugin logs. Use **WPsigner → More → System Status** to test email and identify blocked AJAX actions.

### Signers are unexpectedly asked for a gate

Check both the global policy and the document's Review settings. **Always** overrides per-document choice; **Per document** follows the document's saved security settings.

### The score is lower than expected

Confirm the Digital ID is active and the selected TSA provider is recognized. KYC and access codes do not increase the current score.

### Require WordPress login cannot stay checked

The signer email must already belong to a WordPress user. Create that account first, or leave the option off. WPsigner does not create users.

You also cannot turn the checkbox on while the document has an **active public campaign**, and you cannot activate a campaign if any named signer already has the gate on.

### Signer sees a WordPress login page instead of the PDF

That row has **Require WordPress login with this email** on. They must sign in with the WordPress account that uses the same email, then they return to the signing link. A different logged-in account is rejected.

## Related guides

- [Creating Documents](/core-features/creating-documents/#wordpress-users) — user picker, Add me as signer #1, and the checkbox
- [Didit.me KYC](/integrations/didit/)
- [Digital ID](/digital-identity/digital-id/)
- [Timestamping](/digital-identity/timestamping/)
- [Audit Trails](/digital-identity/audit-trails/)
- [System Status, Storage & Retention](/getting-started/system-status-and-storage/)

---

# Team Roles & Permissions

> Control who can create, view, manage, and administer WPsigner documents without granting every team member full WordPress Administrator access.

edition: pro
Edition: Pro
AI note: This page requires WPsigner Pro. Do not tell Lite users they already have this feature.
HTML: https://docs.wpsigner.com/core-features/team-roles/
Markdown: https://docs.wpsigner.com/md/core-features/team-roles.md

WPsigner adds four team roles on top of a user's normal WordPress role. Use them to separate document creation, organization-wide visibility, management, and administration.

> **Requires WPsigner Pro**
Team roles and the Users access matrix are **Pro** features. [Upgrade to Pro](https://wpsigner.com/pricing/?utm_source=docs&utm_medium=upgrade&utm_campaign=team-roles) · [Lite vs Pro](/getting-started/lite-vs-pro/)

## Assign access

1. Sign in as a WordPress Administrator.
2. Go to **WPsigner → More → Users**.
3. Find the WordPress user.
4. Choose **Sender**, **Viewer**, **Manager**, **Admin**, or **No Access**.
5. Save the change.

WordPress Administrators are not listed because they already receive full WPsigner access through `manage_options`.

> **note**
A WPsigner role is additive. Assigning **Sender**, for example, does not replace the user's existing Subscriber, Editor, or other WordPress role.

## Role matrix

| Ability | Sender | Viewer | Manager | WPsigner Admin | WordPress Administrator |
|---------|:------:|:------:|:-------:|:--------------:|:-----------------------:|
| Open WPsigner | Yes | Yes | Yes | Yes | Yes |
| Create and send documents | Yes | No | Yes | Yes | Yes |
| Create campaigns | Yes | No | Yes | Yes | Yes |
| View own documents | Yes | Yes | Yes | Yes | Yes |
| View all users' documents | No | Yes | Yes | Yes | Yes |
| Edit/delete other users' documents | No | No | Yes | Yes | Yes |
| View audit trails | Own | All | All | All | All |
| View sensitive signer details on other users' documents | No | No | Yes | Yes | Yes |
| Manage WPsigner users | No | No | No | Yes | Yes |
| Manage settings and integrations | No | No | No | See note below | Yes |

## Roles explained

### Sender

For team members who prepare and send their own documents and campaigns. Senders cannot browse or manage documents created by other users.

### Viewer

Provides organization-wide read-only visibility. Viewers can see all documents and audit trails, but cannot create documents or modify another user's records. Sensitive signer details remain restricted unless the document belongs to that Viewer.

### Manager

For operational leads who need to create documents and manage documents from the whole organization. Managers do not receive access to administrative settings or user-role management.

### WPsigner Admin

Receives WPsigner's administrative capabilities, including users and settings at the role level.

> **Current settings-screen requirement**
Several WPsigner settings screens currently perform an additional WordPress `manage_options` check. A user with only the WPsigner **Admin** role may see the navigation link but receive an empty or inaccessible settings screen. Use a WordPress Administrator for Security, Storage, System Status, Webhooks, API keys, and other site-wide configuration until this product limitation is removed.

### WordPress Administrator

WordPress Administrators receive full WPsigner access automatically, even without a separate WPsigner role.

## Document ownership rules

- The WordPress user who creates a document is its owner.
- Senders are filtered to their own documents and campaigns.
- Viewers, Managers, WPsigner Admins, and WordPress Administrators can list all documents.
- Only Managers and administrators can modify another user's document.
- A Viewer's own legacy document may still pass the ownership check for modification, but the Viewer role does not expose the create workflow.

## Client Portal behavior

The `[insigner_admin_portal]` shortcode follows the same visibility rules:

- Sender: own documents.
- Viewer: all documents, read-only for other owners.
- Manager: all documents, with management permissions.
- WPsigner Admin / WordPress Administrator: all documents.

The signer portal, `[insigner_client_portal]`, is different: any logged-in WordPress user can use it, and documents are matched by email instead of WPsigner role.

## Capability reference

For custom code and role-management plugins, WPsigner uses these capabilities:

| Capability | Purpose |
|------------|---------|
| `wps_access` | Open WPsigner |
| `wps_create_documents` | Create documents |
| `wps_send_documents` | Send signing requests |
| `wps_create_campaigns` | Create public campaigns |
| `wps_view_all` | View all users' documents |
| `wps_manage_all` | Modify all users' documents |
| `wps_manage_settings` | Manage WPsigner settings |
| `wps_manage_users` | Assign WPsigner roles |
| `wps_manage_templates` | Manage templates |
| `wps_manage_webhooks` | Manage webhooks |
| `wps_manage_digital_id` | Manage certificate settings |
| `view_wps_audit` | Read document audit trails |

Do not grant individual capabilities without testing the related screen: some administrative pages also require `manage_options`.

## Troubleshooting

### A team member cannot see WPsigner

Assign one of the four WPsigner roles, confirm the account can log in to WordPress, then sign out and back in.

### A Sender cannot find another user's document

This is expected. Use Viewer for organization-wide read-only access or Manager for organization-wide management.

### A Viewer can see a document but not signer details

Viewer access intentionally limits sensitive details on documents created by another user.

### A WPsigner Admin sees a blank settings page

The current screen also requires `manage_options`. Complete the configuration with a WordPress Administrator.

## Related guides

- [Client Portal](/core-features/client-portal/)
- [Bulk Send](/core-features/bulk-send/) — Senders, Managers, and Admins
- [Appearance](/customization/appearance/) — WordPress Administrator
- [Audit Trails](/digital-identity/audit-trails/)
- [Security & Compliance](/core-features/security-compliance/)

---

# Digital Identity & Security

> Configure signer verification, PDF certificates, cryptographic timestamps, encryption, and audit evidence in WPsigner.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/digital-identity/
Markdown: https://docs.wpsigner.com/md/digital-identity.md

WPsigner supports **signer verification**, **cryptographic timestamping**, and **tamper-evident audit trails**. These features strengthen the evidence associated with signed documents and can support a broader compliance program.

---

## Guides

| Guide | Description |
|-------|-------------|
| [Digital ID (.p12)](/digital-identity/digital-id/) | Import or generate PKI certificates to embed a digital identity into every signed PDF |
| [Timestamping (TSA)](/digital-identity/timestamping/) | Add RFC 3161 timestamps from a trusted authority to prove exactly when a document was signed |
| [Audit Trails](/digital-identity/audit-trails/) | Automatic logging of every action — IP addresses, device info, timestamps, and geolocation |
| [Security & Compliance](/core-features/security-compliance/) | Configure OTP, KYC, access codes, evidence capture, and policy modes |

---

## Why It Matters

Electronic signatures are legally valid in most jurisdictions, but the strength of that validity depends on the evidence you can provide. WPsigner's digital identity features create multiple layers of proof:

| Layer | What It Proves | Technology |
|-------|---------------|------------|
| **Digital Certificate** | Which certificate sealed the completed PDF | X.509 PKI, .p12/.pfx |
| **Timestamp** | When they signed (independently verified time) | RFC 3161 TSA |
| **Audit Trail** | What happened (complete event history) | SHA-256 hashed log entries |
| **Document Hash** | The document wasn't altered after signing | SHA-256 integrity check |

Together, these layers can help provide evidence relevant to **ESIGN**, **UETA**, **eIDAS**, and other electronic-signature frameworks. The required controls depend on the transaction, identity method, provider, and jurisdiction.

---

## How They Work Together

```
Signer Opens Document
        ↓
Signer gates completed (when configured)
        ↓
Signature Captured (drawn, typed, or uploaded)
        ↓
Timestamp Requested (TSA server certifies the time)
        ↓
Audit Trail Updated (action logged with IP, device, hash)
        ↓
PDF Sealed (certificate + timestamp embedded in the file)
```

The final PDF contains the digital certificate, the timestamp token, and a reference to the full audit trail — all embedded directly in the file for independent verification.

---

## Getting Started

- **Start with [Digital ID](/digital-identity/digital-id/)** if you want to embed cryptographic identity into your signed PDFs. You can use a self-generated certificate or import one from a Certificate Authority.
- **Add [Timestamping](/digital-identity/timestamping/)** to prove the exact signing time through an independent third party. WPsigner supports any RFC 3161-compliant TSA.
- **Review [Audit Trails](/digital-identity/audit-trails/)** to understand what WPsigner logs automatically and how to access the trail for compliance or disputes.

> **tip**
Choose controls according to transaction risk. A certificate, trusted timestamp, signer-verification gate, and detailed audit trail provide complementary evidence, but unnecessary identity checks can increase friction and privacy obligations.

---

# Audit Trails

> Understand the chronological evidence WPsigner records for document and signer events, and how to review or export it.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/digital-identity/audit-trails/
Markdown: https://docs.wpsigner.com/md/digital-identity/audit-trails.md

An audit trail is a chronological record of document and signer events. It can provide important evidence about identity, intent, timing, access, and integrity, but it does not automatically make a transaction enforceable or admissible.

## What is an Audit Trail?

An audit trail is a chronological record that captures:

- **Who** - The identity of each person involved
- **What** - Every action taken on the document
- **When** - Exact timestamps of each action
- **Where** - IP addresses and geographic information
- **How** - Device and browser information

This creates an unbroken chain of evidence from document creation to completion.

---

## Why Audit Trails Are Essential

### Legal Foundation

Audit trails provide the legal foundation for electronic signatures under major regulations:

| Regulation | Audit Trail Requirement |
|------------|------------------------|
| **ESIGN Act** | Record of transaction |
| **UETA** | Attribution and intent |
| **eIDAS** | Identification and authentication |
| **HIPAA** | Access logs for PHI |
| **SOX** | Financial record integrity |

### Court Admissibility

In legal proceedings, audit trails provide:

| Evidence Type | What It Proves |
|--------------|----------------|
| **Identity** | Who signed (email, IP, device) |
| **Intent** | Deliberate actions were taken |
| **Timing** | When each action occurred |
| **Integrity** | Document wasn't altered |
| **Delivery** | Notification was sent |

### Non-Repudiation

Non-repudiation means signers cannot deny they signed. Audit trails establish this through:

1. **Unique signing link** - Sent only to signer's email
2. **Access logging** - When link was accessed
3. **Device fingerprint** - Browser and device info
4. **IP geolocation** - Physical location approximation
5. **Action sequence** - Deliberate steps to complete signing

---

## What WPsigner Captures

### Document Events

| Event | Captured Data |
|-------|---------------|
| **Created** | Creator user ID, timestamp, document hash |
| **Sent** | Send time, recipient emails |
| **Viewed** | View time, viewer identity, IP address |
| **Downloaded** | Download time, downloader, IP |
| **Voided** | Void time, reason, user who voided |
| **Expired** | Expiration timestamp |

### Signer Events

| Event | Captured Data |
|-------|---------------|
| **Email Delivered** | Delivery timestamp, email service response |
| **Link Accessed** | Access time, IP address, user agent |
| **Document Viewed** | View duration, pages viewed |
| **Fields Completed** | Each field with timestamp |
| **Signature Drawn** | Stroke data, completion time |
| **Submitted** | Final submission timestamp |
| **Declined** | Decline reason, timestamp |

### Technical Metadata

| Data Point | Description | Purpose |
|------------|-------------|---------|
| **IP Address** | IPv4/IPv6 address | Geographic attribution |
| **User Agent** | Browser and OS | Device identification |
| **Geolocation** | Approximate location | Location verification |
| **Session ID** | Unique session identifier | Action correlation |
| **Timezone** | Signer's timezone | Time context |

---

## Certificate of Completion

### What Is It?

The Certificate of Completion is a human-readable summary of the audit trail, automatically appended to the final signed PDF.

### Why It's Important

- **Self-contained** - All evidence in one document
- **Readable** - Non-technical parties can understand
- **Comprehensive** - Full history at a glance
- **Portable** - Travels with the document forever

### Certificate Contents

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
         CERTIFICATE OF COMPLETION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Document: Service Agreement 2026
Document ID: 7f8c9d2e-1234-5678-abcd-ef1234567890
Status: COMPLETED

DOCUMENT HASH (SHA-256):
a1b2c3d4e5f6789...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                  SIGNERS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Signer 1: John Smith (john@company.com)
• Role: Buyer
• Viewed: Jan 15, 2026 10:32:15 AM UTC
• Signed: Jan 15, 2026 10:35:42 AM UTC
• IP Address: 192.168.1.100
• Device: Chrome 120 on Windows 11

Signer 2: Jane Doe (jane@vendor.com)
• Role: Seller
• Viewed: Jan 15, 2026 2:15:22 PM UTC
• Signed: Jan 15, 2026 2:18:03 PM UTC
• IP Address: 10.0.0.50
• Device: Safari 17 on macOS Sonoma

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                  TIMELINE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Jan 14, 2026 3:00:00 PM - Document created
Jan 14, 2026 3:05:12 PM - Sent for signing
Jan 15, 2026 10:32:15 AM - Viewed by John Smith
Jan 15, 2026 10:35:42 AM - Signed by John Smith
Jan 15, 2026 2:15:22 PM - Viewed by Jane Doe
Jan 15, 2026 2:18:03 PM - Signed by Jane Doe
Jan 15, 2026 2:18:03 PM - Document completed

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Powered by WPsigner | Verify at: wpsigner.com/verify
```

### QR Code Verification

Each certificate includes a QR code that links to an online verification page, allowing anyone to:

- Confirm document authenticity
- View the complete audit trail
- Verify timestamp validity
- Download the original signed PDF

---

## Viewing Audit Trails

### In WordPress Admin

1. Go to **WPsigner → Documents**
2. Click on any document
3. Click the **Audit Trail** tab
4. View complete history with all events

### In the Downloaded PDF

1. Open the signed PDF
2. Scroll to the last page(s)
3. View the Certificate of Completion
4. Scan QR code for online verification

### Via REST API

```http
GET /wp-json/insigner/v1/documents/{id}/audit
```

Returns JSON with complete audit history:

```json
{
  "document_id": 123,
  "events": [
    {
      "type": "created",
      "timestamp": "2026-01-14T15:00:00Z",
      "user_id": 1,
      "ip_address": "192.168.1.1"
    },
    {
      "type": "viewed",
      "timestamp": "2026-01-15T10:32:15Z",
      "signer_id": 1,
      "ip_address": "192.168.1.100",
      "user_agent": "Mozilla/5.0..."
    }
  ]
}
```

---

## Legal Best Practices

### Document Retention

| Industry | Retention Period | Regulation |
|----------|-----------------|------------|
| General business | 7 years | General practice |
| Healthcare | 6-10 years | HIPAA |
| Financial | 7 years | SOX |
| Employment | Duration + 7 years | Various |
| Government | Varies | Specific regulations |

### Backup Strategy

Protect your audit trails:

1. **Regular backups** - Daily database backups
2. **Off-site storage** - Store copies externally
3. **Encryption** - Encrypt backup files
4. **Testing** - Verify restore capability
5. **Retention policy** - Define how long to keep

### Access Control

Limit who can view audit trails:

| Role | Access Level |
|------|-------------|
| **WordPress Administrator / WPsigner Admin** | Full access to all audits |
| **Manager** | Audit trails for all documents |
| **Viewer** | Read-only audit access for all documents; sensitive signer details remain permission-scoped |
| **Sender** | Audit trails for documents they created |

See [Team Roles & Permissions](/core-features/team-roles/) for the full document and signer-detail access matrix.

---

## Audit Trail Integrity

### How Integrity Is Ensured

WPsigner protects audit trail integrity through:

| Protection | Method |
|------------|--------|
| **Immutability** | Events are append-only, never modified |
| **Timestamps** | Server-based, not client-provided |
| **Hashing** | SHA-256 hash of event chain |
| **Database** | Structured storage with constraints |
| **Signing** | Digital signature on completion |

### Tamper Detection

If someone attempts to modify an audit trail:

1. Hash chain breaks
2. Digital signature becomes invalid
3. Adobe Reader shows "Document has been modified"
4. Certificate of Completion doesn't match data

---

## Compliance & Regulations

### ESIGN Act Requirements

The ESIGN Act requires:
- ✅ Record of transaction process
- ✅ Consent to electronic records
- ✅ Ability to retain records

**WPsigner provides**: Complete audit trails fulfill all requirements.

### HIPAA Audit Requirements

For healthcare documents:
- ✅ Access logs (who viewed what, when)
- ✅ User identification
- ✅ Automatic logoff (session management)

**WPsigner provides**: Full access logging with IP and device info.

### SOX Compliance

For financial documents:
- ✅ Document integrity verification
- ✅ Access controls
- ✅ Audit trail of all modifications

**WPsigner provides**: Immutable audit trails with hash verification.

---

## Frequently Asked Questions

### How long are audit trails stored?

By default, audit trails are stored indefinitely in your WordPress database. Define a retention policy based on your industry requirements.

### Can audit trails be exported?

Yes. Export as:
- JSON via REST API
- Part of signed PDF (Certificate of Completion)
- CSV export from admin panel

### What if a signer disputes their signature?

The audit trail provides evidence of:
- Email delivery to their address
- Link accessed from specific IP
- Device information matching their typical device
- Specific actions taken (drawing signature, clicking submit)

This evidence typically resolves disputes definitively.

### Are IP addresses accurate?

IP addresses are captured accurately, but:
- VPNs may mask true location
- Corporate networks may show company IP
- Mobile networks may show carrier IP

The IP combined with other factors (email, device) establishes identity.

---

## Next Steps

- [Digital ID](/digital-identity/digital-id/) - Cryptographic signing
- [Timestamping (TSA)](/digital-identity/timestamping/) - Prove when signed
- [Compliance](/compliance/) - Regulatory requirements

---

# Digital ID (PKI Certificates)

> Configure the PKI certificate WPsigner uses to cryptographically seal completed PDFs and help recipients detect later changes.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/digital-identity/digital-id/
Markdown: https://docs.wpsigner.com/md/digital-identity/digital-id.md

A Digital ID (also called a digital certificate or PKI certificate) lets WPsigner cryptographically seal a completed PDF. This page explains what certificates do, their trust limitations, and how to configure them.

## What is a Digital ID?

A Digital ID is a cryptographic certificate that:

1. **Verifies your identity** - Proves who signed the document
2. **Seals the document** - Creates a tamper-evident container
3. **Establishes trust** - Third-party validation of authenticity
4. **Enables long-term validity** - Signatures remain valid for years

Think of it as a digital passport or notary stamp for your electronic documents.

---

## Why Digital IDs Matter

### The Problem Without Digital IDs

Without a Digital ID, your signed PDF is essentially just an image of a signature placed on a document. Anyone could:

- Modify the document after signing
- Claim the signature was forged
- Dispute when the document was signed
- Question who actually signed

### The Solution With Digital IDs

A Digital ID provides cryptographic proof:

| Without Digital ID | With Digital ID |
|-------------------|-----------------|
| Signature is just an image | Signature is cryptographically bound |
| Document can be modified | Any modification breaks the seal |
| No identity verification | Identity verified by certificate |
| Less independent integrity evidence | Stronger technical evidence |
| Fewer compliance controls | Can support a broader compliance program |

---

## Legal Importance

### Regulatory Compliance

Digital IDs enable compliance with major e-signature regulations:

| Regulation | Region | Digital ID Role |
|------------|--------|-----------------|
| **ESIGN Act** | USA | Provides intent attribution |
| **UETA** | USA (all states) | Establishes signer identity |
| **eIDAS** | European Union | Required for Advanced/Qualified signatures |
| **ZertES** | Switzerland | Required for qualified signatures |
| **IT Act** | India | Required for legally valid signatures |

### Court Admissibility

In a dispute, a valid certificate signature can provide evidence that:

- **Certificate identity** - Identifies the certificate that sealed the PDF
- **Tamper evidence** - Later PDF changes can invalidate the signature
- **Integrity** - Connects the signed byte range to the certificate's private key
- **Time evidence** - A trusted timestamp can establish independent time evidence

It does not by itself prove the human signer's identity or make a document automatically admissible or enforceable.

### Industry Requirements

Certain industries require digital certificates:

| Industry | Requirement | Reason |
|----------|-------------|--------|
| **Healthcare** | HIPAA compliance | PHI protection |
| **Finance** | SOX, PCI-DSS | Financial records integrity |
| **Government** | NIST, FedRAMP | Security standards |
| **Legal** | Bar association rules | Document authenticity |
| **Pharma** | FDA 21 CFR Part 11 | Regulatory submissions |

---

## Types of Digital Certificates

### Self-Signed Certificates

Created by you, for internal use.

**Best For:**
- Internal company documents
- Testing and development
- Non-legal agreements
- Team acknowledgments

**Pros:**
- Free to create
- Instant availability
- Full control

**Cons:**
- Not trusted by default in Adobe Reader
- Recipients see "Unknown Signer" warning
- Less credible for external parties

### Commercially Issued Certificates

Purchased from a trusted Certificate Authority (CA).

**Best For:**
- Client-facing contracts
- Legal agreements
- Regulatory filings
- Any document requiring third-party validation

**Pros:**
- Automatically trusted in Adobe Reader
- CA verifies your identity
- Stronger third-party trust signal
- Green checkmark in Adobe

**Cons:**
- Annual cost ($200-$500/year)
- Identity verification process
- Renewal required

### Certificate Authority Comparison

| Certificate Authority | Price Range | Verification Level |
|----------------------|-------------|-------------------|
| **DigiCert** | $300-500/yr | Organization validated |
| **Sectigo (Comodo)** | $150-300/yr | Organization validated |
| **GlobalSign** | $250-400/yr | Organization validated |
| **SSL.com** | $150-250/yr | Individual/Organization |
| **Entrust** | $300-500/yr | Enterprise grade |

> **tip**
For most businesses, **DigiCert** or **GlobalSign** offer the best balance of trust and support. Their certificates are on Adobe's Approved Trust List (AATL).

---

## How Digital Signing Works

### The Signing Process

When WPsigner finalizes a document with your Digital ID:

```
1. Document Hash Created
   └─ SHA-256 hash of entire PDF content
   
2. Hash Encrypted
   └─ Your private key encrypts the hash
   
3. Signature Embedded
   └─ Encrypted hash + your certificate added to PDF
   
4. Timestamp Applied
   └─ TSA server certifies the signing time
   
5. Sealed PDF Created
   └─ Final document with digital signature
```

### Verification Process

When someone opens the signed PDF in Adobe Reader:

```
1. Extract Signature
   └─ Adobe reads the embedded signature
   
2. Verify Certificate
   └─ Checks if CA is trusted (AATL)
   
3. Validate Hash
   └─ Recalculates hash and compares
   
4. Check Timestamp
   └─ Verifies signing time
   
5. Display Status
   └─ ✅ Valid or ❌ Invalid
```

---

## Configuring Your Digital ID

### Accessing Digital ID Settings

1. Go to **WPsigner → More → Digital ID**
2. Use **WPsigner → More → Security & Compliance** to configure the related signature security policies and timestamp provider

### Option 1: Generate Self-Signed Certificate

For testing or internal use:

1. Click **Generate Self-Signed Certificate**
2. Fill in the certificate details:

| Field | Description | Example |
|-------|-------------|---------|
| **Common Name** | Your name or company | Acme Corporation |
| **Organization** | Company name | Acme Corp |
| **Department** | Optional department | Legal Department |
| **City** | Your city | San Francisco |
| **State/Province** | Your state | California |
| **Country** | Two-letter code | US |
| **Email** | Contact email | legal@acme.com |
| **Valid Years** | Certificate lifetime | 3 years |

3. Click **Generate Certificate**
4. Certificate is created and activated immediately

### Option 2: Upload Commercial Certificate

For production use with purchased certificate:

1. Obtain a .p12 or .pfx file from your CA
2. Click **Upload Certificate**
3. Select your .p12/.pfx file
4. Enter the certificate password
5. Click **Upload and Activate**

### Certificate File Formats

| Format | Extension | Description |
|--------|-----------|-------------|
| **PKCS#12** | .p12, .pfx | Contains private key + certificate |
| **PEM** | .pem, .crt | Certificate only (convert to .p12) |
| **DER** | .der, .cer | Binary format (convert to .p12) |

WPsigner accepts **.p12** and **.pfx** files directly.

---

## Adobe Trust List (AATL)

### What is AATL?

The Adobe Approved Trust List is a list of Certificate Authorities that Adobe automatically trusts. When you sign with an AATL certificate:

- Adobe Reader shows a **green checkmark** ✅
- Recipients see "Signature is VALID"
- No manual trust configuration needed
- Maximum legal credibility

### AATL Members Include:

- DigiCert
- GlobalSign
- Sectigo
- Entrust
- IdenTrust
- DocuSign (certificate program)
- SwissSign

### Non-AATL Certificates

Self-signed certificates show:

- Yellow warning triangle ⚠️
- "Signature validity is UNKNOWN"
- Recipient must manually trust your certificate

The cryptographic signature can still be verified, but recipients must establish trust manually. Legal effect depends on the complete transaction and applicable law.

---

## Certificate Best Practices

### Security

| Practice | Why |
|----------|-----|
| **Strong password** | Protect your private key |
| **Secure storage** | Store .p12 file safely |
| **Limited access** | Only authorized staff should access |
| **Backup** | Keep secure backup of certificate |
| **Regular rotation** | Replace before expiration |

### Organizational

| Practice | Why |
|----------|-----|
| **Centralized management** | One certificate for all documents |
| **Document policy** | Define which docs need signing |
| **Training** | Educate staff on certificate importance |
| **Audit logging** | Track certificate usage |

### Renewal Planning

Certificates expire. Plan ahead:

1. **Set calendar reminder** - 60 days before expiration
2. **Budget annually** - Include in IT budget
3. **Test new certificate** - Verify before old expires
4. **Update WPsigner** - Upload new certificate

---

## Troubleshooting

### "Certificate password incorrect"

- Verify the password provided by your CA
- Passwords are case-sensitive
- No spaces before/after password

### "Certificate format not supported"

- Convert to .p12 format using OpenSSL:
```bash
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt
```

### "Certificate has expired"

- Purchase a renewal from your CA
- Generate a new self-signed certificate
- Upload the new certificate to WPsigner

### Adobe shows "Signature validity unknown"

For self-signed certificates, recipients must:
1. Click on the signature
2. Click "Validate Signature"
3. Choose "Trust this certificate"

---

## Certificate vs No Certificate

### Documents Signed Without Digital ID

```
┌─────────────────────────────────┐
│ Signed PDF                      │
│ ┌─────────────────────────────┐ │
│ │ [Signature Image]           │ │
│ │  - Just a PNG image         │ │
│ │  - No cryptographic seal    │ │
│ │  - Can be modified          │ │
│ └─────────────────────────────┘ │
│ ⚠️ No verification available    │
└─────────────────────────────────┘
```

### Documents Signed With Digital ID

```
┌─────────────────────────────────┐
│ Digitally Signed PDF           │
│ ┌─────────────────────────────┐ │
│ │ [Signature + Certificate]   │ │
│ │ ┌───────────────────────┐   │ │
│ │ │ SHA-256 Hash          │   │ │
│ │ │ Private Key Signature │   │ │
│ │ │ X.509 Certificate     │   │ │
│ │ │ RFC 3161 Timestamp    │   │ │
│ │ └───────────────────────┘   │ │
│ └─────────────────────────────┘ │
│ ✅ Signature valid. Document    │
│    has not been modified.       │
└─────────────────────────────────┘
```

---

## Frequently Asked Questions

### Do I need a Digital ID for legal signatures?

For basic contracts in the US under ESIGN/UETA, a signature without Digital ID can be legally valid. However, a Digital ID provides much stronger legal protection and is recommended for:
- High-value contracts
- Regulated industries
- International agreements
- Long-term records

### Can I use one certificate for multiple documents?

Yes. Your certificate is reused for all documents you sign. There's no per-document cost or limit.

### What happens if my certificate expires?

- Previously signed documents remain valid (signature was valid at signing time)
- New documents cannot be signed until you upload a new certificate
- Consider timestamping to extend long-term validity

### Is a self-signed certificate legally valid?

A self-signed certificate can provide integrity evidence, but it does not provide third-party identity validation. Whether the overall electronic signature is legally effective depends on the transaction, signer evidence, consent, retention, and applicable law.

---

## Next Steps

- [Audit Trails](/digital-identity/audit-trails/) - Understand the legal record
- [Timestamping (TSA)](/digital-identity/timestamping/) - Prove when documents were signed
- [Compliance](/compliance/) - Regulatory requirements

---

# Document Encryption

> How WPsigner encrypts documents at rest with AES-256-GCM, and how to configure a dedicated encryption key for maximum security.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/digital-identity/encryption/
Markdown: https://docs.wpsigner.com/md/digital-identity/encryption.md

WPsigner encrypts all uploaded documents and signature images at rest using **AES-256-GCM**, the same encryption standard used by banks and government agencies. This ensures that even if your server's filesystem or database is compromised, your documents remain unreadable.

## How It Works

### Encryption at Rest

When a document is uploaded to WPsigner:

1. **Random filename generated** — A cryptographically random 128-bit filename replaces the original
2. **File encrypted** — AES-256-GCM encrypts the file contents with a unique IV (initialization vector)
3. **Stored securely** — The encrypted file is saved with a `.enc` extension
4. **Decrypted on demand** — Only when an authorized user requests the file

| Layer | Protection |
|-------|-----------|
| **Encryption** | AES-256-GCM (authenticated encryption) |
| **Filename** | Random 128-bit hex (impossible to guess) |
| **Access control** | `.htaccess` blocks direct URL access |
| **Directory listing** | `index.php` prevents browsing |

### What Gets Encrypted

| Content | Encrypted? |
|---------|-----------|
| Uploaded PDF documents | ✅ Yes |
| Signature images | ✅ Yes |
| Completed signed PDFs | Generated on-the-fly |
| Database records | No (metadata only) |

---

## Encryption Key

WPsigner derives its encryption key automatically from your WordPress security salts (`AUTH_KEY` and `SECURE_AUTH_SALT` in `wp-config.php`). This works out of the box, but has one risk: **if those salts are ever regenerated, all encrypted documents become permanently unreadable**.

### Why Define a Dedicated Key

Defining `WPS_ENCRYPTION_KEY` in your `wp-config.php` eliminates this risk entirely:

| Scenario | Without `WPS_ENCRYPTION_KEY` | With `WPS_ENCRYPTION_KEY` |
|----------|------------------------------|---------------------------|
| Normal operation | ✅ Works | ✅ Works |
| WordPress salts rotated | ❌ **Documents lost** | ✅ No impact |
| Security plugin regenerates salts | ❌ **Documents lost** | ✅ No impact |
| Migrate to new server | ⚠️ Must copy exact salts | ✅ Just copy the key |
| Multiple environments | ⚠️ Must sync salts | ✅ Share one key |

> **caution**
WordPress security plugins like **Solid Security (iThemes)**, **Wordfence**, and **SG Security** can regenerate salts with a single click. If you haven't defined `WPS_ENCRYPTION_KEY`, this can make encrypted documents permanently inaccessible.

---

## Setting Up Your Encryption Key

### Step 1: Generate a Key

WPsigner shows a generated key in the admin notice. You can also generate one manually:

**Using WP-CLI:**

```bash
wp eval "echo base64_encode(random_bytes(32));"
```

**Using PHP:**

```php
echo base64_encode(random_bytes(32));
```

This produces a 44-character Base64 string like `a8f3c9d1e6b20a4f7b8c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3g==`.

### Step 2: Add to wp-config.php

Open your `wp-config.php` file and add this line **before** the line that says `/* That's all, stop editing! */`:

```php
define('WPS_ENCRYPTION_KEY', 'your-generated-key-here');
```

### Step 3: Save Your Key

> **important**
**Store your encryption key in a secure location** (password manager, encrypted note, or offline backup). If you lose this key and need to reinstall WordPress, your encrypted documents cannot be recovered.

Recommended backup locations:

- Password manager (1Password, Bitwarden, etc.)
- Encrypted USB drive
- Printed and stored in a safe
- Your hosting provider's secret management

### Step 4: Verify

After adding the key, go to any WPsigner admin page. The security recommendation notice should disappear, confirming that WPsigner is now using your dedicated key.

---

## Key Priority

WPsigner checks for encryption keys in this order:

| Priority | Source | Where it lives |
|----------|--------|---------------|
| 1 (highest) | `WPS_ENCRYPTION_KEY` constant | `wp-config.php` (filesystem) |
| 2 (fallback) | Derived from WordPress salts | `wp-config.php` (filesystem) |

In both cases, the key **never** touches the database. It exists only in `wp-config.php` on the filesystem, protecting against SQL injection attacks.

---

## Salt Mismatch Warning

If WPsigner detects that your WordPress salts have changed (and you haven't defined `WPS_ENCRYPTION_KEY`), it will show a **critical red notice** in the admin:

> 🚨 **WPsigner — Encryption Key Changed**
> WordPress security salts have been regenerated. Previously encrypted documents cannot be decrypted with the current salts.

### How to Recover

1. **Restore original salts** — Find the original `AUTH_KEY` and `SECURE_AUTH_SALT` values from a backup of your `wp-config.php` and restore them
2. **If no backup exists** — The encrypted documents are permanently lost. You can dismiss the notice to reset the key for future documents

### Preventing This Issue

The best prevention is to define `WPS_ENCRYPTION_KEY` **before** any salt rotation occurs. Once defined, salt changes have zero impact on document encryption.

---

## Technical Details

### Cipher Specification

| Parameter | Value |
|-----------|-------|
| **Algorithm** | AES-256-GCM |
| **Key size** | 256 bits (32 bytes) |
| **IV size** | 96 bits (12 bytes, per NIST recommendation) |
| **Authentication tag** | 128 bits (16 bytes) |
| **Key derivation** | HMAC-SHA256 (when using salt fallback) |

### Why AES-256-GCM?

- **Authenticated encryption** — Detects any tampering with encrypted data
- **NIST approved** — Standard for US government classified information
- **Performance** — Hardware-accelerated on modern CPUs (AES-NI)
- **No padding oracle attacks** — GCM mode is immune to these

### File Format

Encrypted files are stored as:

```
Base64( IV (12 bytes) + Auth Tag (16 bytes) + Ciphertext )
```

The IV is generated using PHP's `random_bytes()` (CSPRNG) for each encryption operation, ensuring no two files share an IV.

---

## Frequently Asked Questions

### What happens if I change my WPS_ENCRYPTION_KEY?

All previously encrypted documents will become unreadable. Only change this key if you have no existing encrypted documents, or if you're prepared to lose access to them.

### Can I disable encryption?

Encryption is applied automatically when the OpenSSL extension is available (which is standard on all modern PHP installations). If OpenSSL is not available, files are stored without encryption with a warning in the logs.

### Does encryption affect performance?

Minimally. AES-256-GCM with hardware acceleration (AES-NI) encrypts at several GB/s. For typical documents (1-10MB), the overhead is imperceptible.

### Is the encryption key exposed in the database?

**No.** Whether you use `WPS_ENCRYPTION_KEY` or the salt-derived fallback, the key exists only in `wp-config.php` on the filesystem. A database breach (SQL injection) cannot expose the encryption key.

---

## Next Steps

- [Timestamping (TSA)](/digital-identity/timestamping/) — Add cryptographic timestamps to documents
- [Audit Trails](/digital-identity/audit-trails/) — Understanding the legal record
- [Digital ID](/digital-identity/digital-id/) — Configure your signing certificate

---

# Timestamping (TSA)

> Configure RFC 3161 timestamping to add independent cryptographic time evidence to completed PDFs.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/digital-identity/timestamping/
Markdown: https://docs.wpsigner.com/md/digital-identity/timestamping.md

Timestamping adds an independently signed time assertion for a document hash. It can support long-term verification when the certificate chain, timestamp token, revocation information, and PDF signature remain valid.

> **Lite vs Pro**
**Lite** records a **local** completion timestamp on your server. **External TSA** (RFC 3161) providers require **Pro**. [Lite vs Pro](/getting-started/lite-vs-pro/) · [Upgrade to Pro](https://wpsigner.com/pricing/?utm_source=docs&utm_medium=upgrade&utm_campaign=timestamping)

## What is Timestamping?

A timestamp is a digitally signed assertion from a trusted third party (Timestamp Authority or TSA) that certifies:

1. **The document existed** at a specific moment
2. **The exact time** down to the second
3. **Independent verification** - not from your server

Think of it as a digital notary's date stamp that can never be forged or disputed.

---

## Why Timestamps Matter

### The Problem They Solve

Without timestamps, several issues arise:

| Problem | Risk | Example |
|---------|------|---------|
| **Backdating** | Someone claims document was signed earlier | Antedating a contract |
| **Expiration disputes** | Unclear if signed before deadline | Insurance claims |
| **Certificate expiry** | Signature invalid after cert expires | Old agreements |
| **Time manipulation** | Server clock changes | Fraud attempts |

### The Solution Timestamps Provide

| Benefit | How Timestamps Help |
|---------|---------------------|
| **Immutable proof** | Third-party certifies the exact moment |
| **Long-term validity** | Valid decades after certificate expires |
| **Independent verification** | Not dependent on your server |
| **Non-repudiation** | Signer cannot claim different date |
| **Regulatory compliance** | Meets strict archival requirements |

---

## Legal Importance

### Long-Term Validation (LTV)

LTV ensures signatures remain valid indefinitely:

| Without LTV | With LTV (Timestamp) |
|-------------|---------------------|
| Signature expires with certificate | Signature valid forever |
| Must verify against expired cert | Timestamp proves signing date |
| Questionable after years | Holds up in court decades later |
| Not suitable for archives | Perfect for long-term storage |

### Regulatory Requirements

Many regulations require or recommend timestamping:

| Regulation | Timestamping Requirement |
|------------|--------------------------|
| **eIDAS (EU)** | Required for Qualified Signatures |
| **FDA 21 CFR Part 11** | Required for pharma records |
| **HIPAA** | Recommended for healthcare records |
| **SOX** | Recommended for financial records |
| **ISO 27001** | Best practice for compliance |

### Court Acceptability

In legal proceedings, timestamps provide:

- **Definitive proof** of when signature occurred
- **Third-party validation** (not self-asserted)
- **Cryptographic evidence** that's mathematically verifiable
- **Chain of custody** for document timing

---

## How Timestamping Works

### The Technical Process

When WPsigner creates a timestamp:

```
1. Document Hash Created
   └─ SHA-256 hash of the signed document
   
2. Timestamp Request Sent
   └─ Hash sent to TSA server (not the document)
   
3. TSA Signs the Hash + Time
   └─ TSA adds current time and digitally signs
   
4. Timestamp Response Returned
   └─ Signed timestamp token received
   
5. Timestamp Embedded in PDF
   └─ Token stored in document signature
```

### What Gets Sent to TSA?

**Only the document hash** - not the document itself.

| Sent | NOT Sent |
|------|----------|
| SHA-256 hash (32 bytes) | Document content |
| | Signer information |
| | Any personal data |

This means your documents remain completely private while still getting verified timestamps.

### Verification Process

When someone verifies a timestamped document:

1. Adobe extracts the timestamp token
2. Verifies TSA's digital signature
3. Confirms the hash matches the document
4. Displays the verified signing time

---

## RFC 3161 Standard

### What is RFC 3161?

RFC 3161 is the Internet standard for trusted timestamping, published by the IETF. It defines:

- Request/response format
- Cryptographic requirements
- Trust model
- Implementation guidelines

### RFC 3161 Compliance

WPsigner fully implements RFC 3161:

| Feature | Status |
|---------|--------|
| Standard request format | ✅ Compliant |
| SHA-256 hash algorithm | ✅ Supported |
| Nonce inclusion | ✅ Implemented |
| Certificate chain | ✅ Embedded |
| Response validation | ✅ Verified |

---

## Configuring Timestamping

### Accessing TSA Settings

1. Go to **WPsigner → More → Security & Compliance**
2. Find the **Timestamping** section
3. Enable timestamping with the toggle

### Configuration Options

| Setting | Description | Example |
|---------|-------------|---------|
| **Enable Timestamping** | Turn on/off | On |
| **TSA URL** | Timestamp server address | https://freetsa.org/tsr |
| **TSA Username** | If authentication required | (optional) |
| **TSA Password** | If authentication required | (optional) |
| **Hash Algorithm** | Hash type to use | SHA-256 |

### Default Configuration

WPsigner comes pre-configured with FreeTSA.org:

```
TSA URL: https://freetsa.org/tsr
Authentication: None required
Hash: SHA-256
```

This works immediately with no configuration needed.

---

## Timestamp Authorities

### Free TSA Services

| Provider | URL | Notes |
|----------|-----|-------|
| **FreeTSA.org** | https://freetsa.org/tsr | Free, reliable |
| **DigiCert** | https://timestamp.digicert.com | Free tier available |
| **Sectigo** | http://timestamp.sectigo.com | Free |
| **Apple** | http://timestamp.apple.com/ts01 | Free |

### Commercial TSA Services

For higher volumes or SLA guarantees:

| Provider | Features | Pricing |
|----------|----------|---------|
| **DigiCert** | High availability, support | Contact sales |
| **GlobalSign** | Enterprise SLA | Contact sales |
| **SwissSign** | Swiss privacy laws | Contact sales |
| **Entrust** | Government-grade | Contact sales |

### Choosing a TSA

Consider these factors:

| Factor | Importance | Notes |
|--------|------------|-------|
| **Reliability** | Critical | Must be available 24/7 |
| **Speed** | Important | Should respond in < 1 second |
| **Trust** | Critical | Well-known, established provider |
| **Location** | Consider | May matter for data residency |
| **Cost** | Variable | Free options available |

> **tip**
For most users, **FreeTSA.org** or **DigiCert's free service** is sufficient. Only consider paid services for enterprise volumes (1000+ documents/day) or strict SLA requirements.

---

## Testing Your Configuration

### Manual Test

1. Go to **WPsigner → More → Security**
2. Click **Test Timestamp Server**
3. WPsigner sends a test request
4. Result shows success or error message

### Verify in Signed PDF

1. Create and sign a test document
2. Download the completed PDF
3. Open in Adobe Reader
4. Click on the signature
5. View signature details
6. Check for "Timestamp" entry with time

### What Success Looks Like

In Adobe Reader, you'll see:

```
Signature is VALID
- Signed by: Your Name
- Signing time: Jan 15, 2026 2:30:15 PM
- The signature includes an embedded timestamp ✅
- Timestamp verified by: FreeTSA
```

---

## Understanding Timestamp Validity

### Timestamp vs Certificate Expiry

| Scenario | Signature Status |
|----------|-----------------|
| Certificate valid, no timestamp | ✅ Valid until cert expires |
| Certificate expired, no timestamp | ⚠️ Validity unknown |
| Certificate valid, with timestamp | ✅ Valid |
| Certificate expired, with timestamp | ✅ Still valid (LTV) |

### Long-Term Validation Explained

With a timestamp, validity works like this:

1. **At signing time**: Certificate was valid → timestamp records this
2. **Years later**: Certificate has expired
3. **Verification**: Timestamp proves cert was valid when signed
4. **Result**: Signature still valid, indefinitely

This is why timestamps are essential for documents you need to keep for years.

---

## Performance Considerations

### Timestamp Request Time

Each document requires a round-trip to the TSA:

| Factor | Impact |
|--------|--------|
| **TSA location** | Closer = faster |
| **Network latency** | Typically 100-500ms |
| **TSA load** | Varies by provider |
| **Your server location** | Affects latency |

### Optimization

For high-volume signing:

1. **Use a reliable TSA** - Avoid slow or unreliable servers
2. **Consider location** - Use geographically close TSA
3. **Background processing** - Timestamp asynchronously if possible
4. **Caching** - Not applicable (each doc needs unique timestamp)

---

## Troubleshooting

### "Timestamp request failed"

**Causes:**
- TSA server is down
- Network connectivity issues
- Incorrect TSA URL
- Firewall blocking requests

**Solutions:**
1. Test the TSA URL directly: `curl -I https://freetsa.org/tsr`
2. Try a different TSA server
3. Check firewall rules for outbound HTTPS
4. Verify server has internet access

### "Invalid timestamp response"

**Causes:**
- TSA server misconfiguration
- Response format error
- Certificate chain issue

**Solutions:**
1. Try a different TSA
2. Update PHP OpenSSL extension
3. Check PHP error logs for details

### "Timestamp not appearing in PDF"

**Causes:**
- Timestamping not enabled
- TSA request failed silently
- PDF generation issue

**Solutions:**
1. Verify timestamping is enabled in settings
2. Check that test timestamp works
3. Review document generation logs

---

## Comparing With and Without Timestamps

### Document Without Timestamp

```
┌─────────────────────────────────────┐
│ Signed PDF                          │
│ ┌─────────────────────────────────┐ │
│ │ Digital Signature               │ │
│ │ • Signed: [Server time]         │ │
│ │ • Certificate valid until 2027  │ │
│ └─────────────────────────────────┘ │
│                                     │
│ ⚠️ In 2028: "Certificate expired,  │
│    signature validity unknown"      │
└─────────────────────────────────────┘
```

### Document With Timestamp

```
┌─────────────────────────────────────┐
│ Signed PDF with Timestamp           │
│ ┌─────────────────────────────────┐ │
│ │ Digital Signature               │ │
│ │ • Signed: Jan 15, 2026 2:30 PM │ │
│ │ • Certificate valid until 2027  │ │
│ │ ┌───────────────────────────┐   │ │
│ │ │ RFC 3161 Timestamp        │   │ │
│ │ │ • Time: Jan 15, 2026      │   │ │
│ │ │ • TSA: FreeTSA.org        │   │ │
│ │ │ • Hash verified ✓         │   │ │
│ │ └───────────────────────────┘   │ │
│ └─────────────────────────────────┘ │
│                                     │
│ ✅ In 2028 and beyond: "Signature  │
│    valid. Timestamp verified."      │
└─────────────────────────────────────┘
```

---

## Frequently Asked Questions

### Is timestamping required for legal validity?

For basic e-signatures in the US, no. However, timestamps are required or recommended for:
- European qualified signatures (eIDAS)
- Pharmaceutical submissions (FDA)
- Long-term archival documents
- High-value contracts

### Does timestamping slow down signing?

Minimally. Typical overhead is 100-500ms per document. Users won't notice this in the signing flow.

### What if the TSA is down?

WPsigner will:
1. Retry the request
2. If still failing, complete signature without timestamp
3. Log the failure for your review

You can enforce timestamps by enabling "Require Timestamp" in settings.

### Can I add timestamps to old documents?

No. Timestamps must be applied at signing time. They prove when the signature was created - adding one later would defeat the purpose.

---

## Next Steps

- [Digital ID](/digital-identity/digital-id/) - Configure your certificate
- [Audit Trails](/digital-identity/audit-trails/) - Understanding the legal record
- [Compliance](/compliance/) - Regulatory requirements

---

# System Status, Storage & Retention

> Diagnose WPsigner requirements, cron, email, PDF, database, and storage health; configure retention and understand destructive cleanup actions.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/getting-started/system-status-and-storage/
Markdown: https://docs.wpsigner.com/md/getting-started/system-status-and-storage.md

WPsigner provides two operational screens:

- **WPsigner → More → System Status** — diagnostics, health checks, and repair actions.
- **WPsigner → More → Storage & Retention** — storage usage, cloud backup status, retention, purge, and full deletion.

Both screens currently require a WordPress Administrator with `manage_options`.

## System Status

System Status checks:

- WordPress, PHP, and extension requirements
- Plugin compatibility
- Secure storage path, permissions, and size
- WP-Cron configuration and scheduled WPsigner jobs
- Email/SMTP delivery
- Timezone
- PDF engine and the active **Signed PDF fonts** pack (if installed)
- Database tables
- Webhooks and REST API
- Security-related configuration

Use **Copy Debug Info** when contacting support. Review the copied text before sharing it because environment reports can include domain, plugin, and server details.

## Scheduled jobs

WPsigner relies on WP-Cron for background work:

| Hook | Schedule | Purpose |
|------|----------|---------|
| `wps_send_automatic_reminders` | Hourly | Send due signing reminders |
| `wps_check_expirations` | Hourly | Expire documents whose due date passed |
| `wps_auto_purge_storage` | Daily when configured | Remove eligible local completed PDFs |
| `wps_ots_check_pending` | When OpenTimestamps is enabled | Check pending timestamp proofs |
| `wps_api_logs_purge` | Daily | Purge old API request logs |

### Repair missing jobs

Click **Fix Cron Jobs** in System Status. WPsigner recreates the schedules appropriate for the enabled features.

If `DISABLE_WP_CRON` is enabled, configure a real server cron to call `wp-cron.php`. Repairing the schedule does not make WordPress cron execute when the hosting environment never triggers it.

## Secure storage

System Status displays the active secure-storage directory and whether it is writable. WPsigner normally stores files below the WordPress uploads area using protected folders and secure-storage controls.

Do not make the storage folder publicly browsable. Back up both:

1. The WordPress database, which contains document, signer, field, audit, and configuration records.
2. The WPsigner file storage, which contains document files.

A file-only or database-only backup is not a complete WPsigner recovery plan.

## Retention settings

Open **Storage & Retention** to configure:

| Setting | Options |
|---------|---------|
| **Automatic purge** | On / Off |
| **Retention period** | Forever, 30, 60, 90, 180, or 365 days |

Automatic purge removes only local PDFs for **completed** documents older than the selected period and only when WPsigner has recorded a cloud backup for that document. Audit records, signatures, and document database records remain.

> **important**
Choosing a retention period does not guarantee deletion of every document file. Files without a confirmed cloud backup are skipped to prevent accidental loss.

## Storage actions

### Purge Completed PDFs

- Requires typing `DELETE`.
- Removes eligible local completed PDFs that have a cloud backup.
- Keeps document records, audit data, and cloud copies.

### Delete Drafts & Cancelled

- Requires typing `DELETE`.
- Removes draft/cancelled records and their local files.
- Use only after confirming those documents are no longer needed.

### Push to Cloud

Scans completed PDFs that lack a recorded cloud backup and uploads them through the configured provider. Check the result before enabling automatic purge.

### Delete Everything

> **danger**
**Delete Everything** is a destructive reset. It removes WPsigner's operational database records and local files. It cannot be undone from WPsigner.

The action requires:

1. An acknowledgement checkbox.
2. The exact phrase `DELETE ALL`.
3. Keeping the browser tab open while chunked file deletion finishes.

It removes documents, signers, fields, audits, templates, campaigns, payments, and related operational records. It preserves WPsigner options and license data. Remote files already stored with a cloud provider are not deleted automatically.

Create and test a full backup before using it. If the browser closes or a timeout interrupts the process, reopen the screen and run the cleanup again after verifying what remains.

## Operational checklist

### Weekly

- Review System Status for new warnings.
- Check failed emails, webhook deliveries, and cron events.
- Confirm available disk space.

### Monthly

- Test a document from upload through final PDF.
- Verify a recent database and file backup can be restored.
- Review API keys, webhook endpoints, and inactive integrations.
- Confirm cloud backup counts before purging local PDFs.

### Before an upgrade

1. Back up database and WPsigner files.
2. Record the current System Status report.
3. Update in staging when possible.
4. Test PDF generation, signing, email, cron, and integrations.

## Troubleshooting

### Cron jobs are missing

Use **Fix Cron Jobs**. If they disappear again, check object caching, cron-management plugins, `DISABLE_WP_CRON`, and the hosting control panel's scheduled task.

### Automatic purge does not remove files

Confirm automatic purge is on, the period is not **Forever**, the document is completed and old enough, and a cloud backup is recorded.

### Storage is not writable

Check the exact path shown in System Status, filesystem ownership, hosting quotas, and security rules. Avoid setting globally writable permissions.

### Emails fail

Use the System Status email test, verify SMTP credentials and DNS, and inspect the mail provider's logs.

### Wordfence blocks WPsigner actions

Use the compatibility information in System Status to allowlist the reported WPsigner AJAX actions, then retest. Do not disable the firewall globally.

### Delete Everything stops partway

Keep the tab open and retry the action. Check PHP execution limits and server logs. Cloud backups remain at the provider until removed there.

## Related guides

- [Hosting Compatibility](/getting-started/hosting-compatibility/)
- [Security & Compliance](/core-features/security-compliance/)
- [Audit Trails](/digital-identity/audit-trails/)
- [Troubleshooting](/support/troubleshooting/)

---

# Didit.me — Identity Verification (KYC)

> Integrate Didit.me identity verification into WPsigner to require signers to verify their identity with a government-issued ID, selfie, and liveness detection before signing.

edition: pro
Edition: Pro
AI note: This page requires WPsigner Pro. Do not tell Lite users they already have this feature.
HTML: https://docs.wpsigner.com/integrations/didit/
Markdown: https://docs.wpsigner.com/md/integrations/didit.md

**Didit.me** is an AI-powered Know Your Customer (KYC) identity verification platform. When integrated with WPsigner, signers must prove their identity using a government-issued ID document, a selfie, and a real-time liveness check before they can sign a document.

Identity verification strengthens the evidence associated with a signing event, but it does not by itself guarantee legal validity or replace advice about the requirements in your jurisdiction.

  
    Compares the selfie with the ID photo using biometric analysis with a confidence score.
  
  
    Prevents spoofing attacks with real-time liveness checks — no photos or videos accepted.
  
  
    Extracts and validates data from passports, national IDs, and driver's licenses from 190+ countries.
  
  
    Verification decisions and relevant metadata are recorded in the WPsigner Activity Timeline; identity images remain with Didit.
  

---

## How It Works

The integration follows a **two-step activation model**:

1. **Configure credentials** in **WPsigner → Integrations → Didit**.
2. **Choose the KYC policy** in **WPsigner → More → Security & Compliance**.

Once enabled, this is the end-to-end flow:

```
Signer opens signing page
        ↓
WPsigner detects KYC is required
        ↓
Signer clicks "Verify Identity"
        ↓
WPsigner calls Didit API → creates a verification session
        ↓
Signer is redirected to Didit's verification page (new tab)
        ↓
Signer completes: ID scan → Selfie → Liveness check
        ↓
Didit sends webhook to WPsigner with result (Approved / Declined)
        ↓
Callback page closes → signing page unlocks automatically
        ↓
Verified signer can now sign the document
```

The signing page polls for status in the background using `BroadcastChannel` and `localStorage` as cross-tab communication mechanisms, meaning the signer never has to manually reload.

---

## Prerequisites

Before setting up the integration you need:

- A **Didit Business account** at [business.didit.me](https://business.didit.me)
- At least one **Verification Workflow** created in the Didit console
- An **API Key** with sufficient permissions
- A **Webhook Secret** from your workflow settings

---

## Setup Guide

1. **Create a Didit Business account**

   Go to [business.didit.me](https://business.didit.me) and register. No credit card is required for the free tier.

2. **Create a Verification Workflow**

   Inside the Didit Business Console:
   - Go to **Workflows** → **Create Workflow**
   - Add the following steps (in order):
     - **ID Document Verification** — scans and validates government-issued ID
     - **Selfie Capture** — takes a photo of the signer
     - **Liveness Detection** — confirms the person is physically present
   - Save and note the **Workflow ID** (a UUID like `550e8400-e29b-41d4-a716-446655440000`)

3. **Get your API Key**

   - Go to **Settings → API Keys** in the Didit Business Console
   - Click **Create API Key**
   - Copy the key immediately — it is only shown once

4. **Get your Webhook Secret**

   - Open your Workflow settings
   - Go to the **Webhook** tab
   - Copy the **Webhook Signing Secret** (used for HMAC-SHA256 signature verification)

5. **Configure WPsigner**

   In your WordPress admin, go to **WPsigner → Integrations → Didit**:
   - Paste your **API Key**
   - Paste your **Workflow ID**
   - Paste your **Webhook Secret**
   - Click **Save Settings**

6. **Register the Webhook URL**

   - Copy the **Webhook URL** shown in the WPsigner Didit settings page
   - It follows this format: `https://yoursite.com/?wps_didit_webhook=1`
   - Go back to Didit Business Console → your Workflow → **Webhook** tab
   - Paste the URL and save

7. **Test the connection**

   Click **Test Connection** in the WPsigner Didit settings page. A success message confirms your API key is valid. The test sends a request to the Didit API and expects a `404` response (a valid key will get a 404 for a non-existent dummy session — that confirms authentication worked).

8. **Enable KYC requirement**

   Go to **WPsigner → More → Security & Compliance** and set the KYC policy to **Always**, **Per document**, or **Off**. With **Per document**, enable KYC in the document's Review step only when it is needed.

---

## Credentials Reference

| Field | Where to Find It | Description |
|-------|-----------------|-------------|
| **API Key** | Business Console → Settings → API Keys | Server-to-server authentication key |
| **Workflow ID** | Business Console → Workflows → (your workflow) | UUID that identifies which verification steps to run |
| **Webhook Secret** | Business Console → Workflows → Webhook tab | HMAC-SHA256 signing secret for webhook verification |
| **Webhook URL** | WPsigner → Integrations → Didit (read-only) | URL Didit will POST results to — register this in your workflow |

All credentials are encrypted at rest and are never stored in plaintext in the database.

---

## Signer Experience

From the signer's perspective, the verification flow is seamless:

1. The signer opens the signing link (`/wpsigner/{token}`)
2. If KYC is required and not yet verified, a verification prompt appears — **they cannot proceed to sign without completing it**
3. Clicking **"Verify My Identity"** creates a session and opens Didit's verification page in a **new tab** (popup)
4. The signer completes three steps within the Didit interface:
   - Scans or photographs their ID document (passport, national ID, or driver's license)
   - Takes a live selfie
   - Completes a liveness challenge (e.g., blink, turn head)
5. Upon completion, the Didit tab closes automatically and the signing page detects the result via `BroadcastChannel` / `localStorage`
6. If approved, the signing interface unlocks and the signer can proceed
7. If declined, an error message is shown and the signer can retry

The entire process typically takes **30–90 seconds**.

---

## Verification Statuses

WPsigner tracks the following KYC statuses per signer:

| Status | Meaning |
|--------|---------|
| `pending` | A session has been created; the signer has not yet completed verification |
| `Started` | The signer has opened the Didit verification page |
| `Callback_Received` | The signer returned from Didit (browser callback received); awaiting authoritative webhook |
| `Approved` | Identity verified — signer can proceed to sign |
| `Declined` | Verification failed — signer cannot sign |
| `Expired` | Session expired before completion (a new session will be created on next attempt) |

**Only `Approved` is authoritative.** The browser callback (`Callback_Received`) is an optimistic UI signal only — the final decision always comes from Didit's server-side webhook. The signing page is only fully unlocked once the webhook confirms `Approved`.

---

## Security Architecture

The integration is designed with a fail-closed security model — when in doubt, it blocks rather than allows.

### Webhook Signature Verification (X-Signature-V2)

Every webhook from Didit includes an `X-Signature-V2` header and an `X-Timestamp` header. WPsigner verifies the webhook before processing:

1. **Timestamp freshness check** — Rejects webhooks older than ±5 minutes to prevent replay attacks
2. **HMAC-SHA256 verification** — Computes `HMAC-SHA256(sorted_json_body, webhook_secret)` and compares with `hash_equals()` (timing-safe comparison)
3. **Fail-closed** — If no webhook secret is configured, all webhooks are rejected with `401`

The signature algorithm:
- Sorts all JSON keys recursively
- Converts integer-value floats to integers
- Encodes with `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`
- Signs with HMAC-SHA256

### Status Immutability

Once a signer's KYC status reaches `Approved`, it **cannot be downgraded** by any subsequent webhook. This prevents an attacker from forging a `Declined` webhook after approval.

### Idempotency & Replay Prevention

Each webhook is deduplicated using a transient key based on `MD5(session_id + status + timestamp)` with a 60-second TTL. Duplicate or replayed webhooks are silently ignored with `200 OK` (to prevent Didit from retrying).

### Token Ownership Verification (IDOR Prevention)

When a signer requests a KYC session via AJAX, WPsigner verifies that the submitted `token` matches the signer's `access_token` using `hash_equals()`. This prevents Insecure Direct Object Reference (IDOR) attacks — a signer cannot create or check sessions for other signers.

### Rate Limiting

| Operation | Limit |
|-----------|-------|
| Create session | 50 attempts per signer per hour |
| Check status (poll) | 60 requests per signer per minute |
| Callback URL | 10 requests per signer per minute |
| Save settings (admin) | 10 saves per user per minute |

### Session Reuse

If a signer already has an active (non-terminal) session, WPsigner reuses the existing Didit verification URL instead of creating a new session. This prevents unnecessary API charges and avoids flooding Didit with duplicate sessions.

Terminal statuses that force a new session: `Declined`, `Expired`, `Failed`, `Abandoned`.

### Credential Storage

Credentials are stored encrypted in WordPress options:

| Option | Content |
|--------|---------|
| `wps_didit_api_key` | AES-256 encrypted API key |
| `wps_didit_workflow_id` | Plain text Workflow UUID |
| `wps_didit_webhook_secret` | AES-256 encrypted webhook secret |

---

## Audit Trail Integration

Every KYC event is automatically logged to the WPsigner Activity Timeline with full detail:

| Event | When it fires | Logged Detail |
|-------|--------------|---------------|
| `kyc_session_started` | When a new verification session is created | Session UUID |
| `kyc_callback_received` | When the user returns from Didit's page | "Awaiting webhook confirmation" note |
| `kyc_verified` | When webhook confirms `Approved` | Document type, issuing country, face match score, liveness result |
| `kyc_declined` | When webhook confirms `Declined` | Provider and session info |

The biometric evidence stored on `Approved` includes:

- `face_match_score` — percentage confidence (e.g., `98.2`)
- `document_type` — e.g., `PASSPORT`, `NATIONAL_ID`, `DRIVER_LICENSE`
- `issuing_country` — ISO 3166-1 alpha-2 country code
- `liveness` — liveness check result
- `provider` — `Didit.me`
- `method` — `ID + Selfie + Liveness`

This data is stored as JSON in the `kyc_data` column and is included in the legal PDF certificate generated at signing completion.

---

## API Reference

WPsigner communicates with the **Didit API v3** at `https://verification.didit.me/v3`.

### Create Session

**Endpoint:** `POST /session/`

Creates a new verification session for a signer.

**Request body sent by WPsigner:**

```json
{
  "workflow_id": "550e8400-e29b-41d4-a716-446655440000",
  "vendor_data": "signer-42",
  "callback": "https://yoursite.com/?wps_didit_callback=1&signer_id=42",
  "callback_method": "both",
  "metadata": "{\"document_id\": 10, \"signer_id\": 42, \"site_url\": \"https://yoursite.com\"}",
  "language": "en",
  "contact_details": {
    "email": "signer@example.com",
    "send_notification_emails": false
  },
  "expected_details": {
    "first_name": "John",
    "last_name": "Doe"
  }
}
```

**Response** (on success):

```json
{
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "url": "https://verify.didit.me/session/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```

WPsigner stores `session_id` and `url` in the `wps_signers` row for that signer.

### Retrieve Session Decision

**Endpoint:** `GET /session/{session_id}/decision/`

Retrieves the authoritative decision for a completed session. Called by WPsigner:
- **Always** when an `Approved` webhook is received (to fetch biometric details)
- **Proactively** when the signer returns from Didit (`Callback_Received` status) to get the decision faster than waiting for the webhook

**Response** (on approval):

```json
{
  "session_id": "a1b2c3d4-...",
  "status": "Approved",
  "features": [
    { "feature": "face_match", "score": 0.982 },
    { "feature": "liveness", "status": "passed" }
  ],
  "id_verifications": [
    {
      "document_type": "PASSPORT",
      "issuing_country": "US"
    }
  ]
}
```

### Authentication

All API requests include:

```http
x-api-key: YOUR_API_KEY
Content-Type: application/json
Accept: application/json
User-Agent: WPsigner/3.x.x
```

---

## Webhook Reference

Didit sends `POST` requests to your configured webhook URL when a session status changes.

### Webhook URL

Your webhook URL (shown in WPsigner settings) follows this format:

```
https://yoursite.com/?wps_didit_webhook=1
```

Make sure your site is publicly accessible from the internet. If you are running WordPress on localhost or behind a firewall, Didit cannot reach your webhook URL. Use a tunneling service like [ngrok](https://ngrok.com) for local testing.

### Webhook Payload

```json
{
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "Approved",
  "vendor_data": "signer-42",
  "metadata": "{\"document_id\": 10, \"signer_id\": 42, \"site_url\": \"https://yoursite.com\"}",
  "features": [
    { "feature": "face_match", "score": 0.982 },
    { "feature": "liveness", "status": "passed" }
  ],
  "id_verifications": [
    {
      "document_type": "PASSPORT",
      "issuing_country": "US"
    }
  ]
}
```

### Webhook Headers

| Header | Description |
|--------|-------------|
| `X-Signature-V2` | HMAC-SHA256 signature of the request body |
| `X-Timestamp` | Unix timestamp of when the request was sent |
| `Content-Type` | `application/json` |

### Allowed Status Values

WPsigner only accepts the following status values from Didit webhooks. Unknown statuses are silently ignored:

- `Approved`
- `Declined`
- `Pending`
- `Started`
- `Expired`

### Webhook Response

WPsigner always responds with `200 OK` and a JSON body. Didit will retry on non-200 responses, so returning 200 even for invalid payloads (after logging) is intentional.

---

## Database Schema

The Didit integration adds four columns to the `{prefix}_wps_signers` table via a one-time migration:

| Column | Type | Description |
|--------|------|-------------|
| `kyc_session_id` | `VARCHAR(100)` | Didit session UUID |
| `kyc_status` | `VARCHAR(50)` | Current KYC status (see status table above) |
| `kyc_verified_at` | `DATETIME` | Timestamp when `Approved` was received |
| `kyc_data` | `LONGTEXT` | JSON blob with biometric evidence and session metadata |

The migration runs automatically on plugin initialization via `WPS_Didit::ensure_tables()`.

---

## Troubleshooting

### "API request failed" on Test Connection

- Double-check the API key has been copied correctly (no trailing spaces)
- Make sure the key has not been revoked in the Didit console
- Test Connection returns `401` or `403` → API key is invalid
- Test Connection returns `404` → API key is valid (expected for dummy UUID)

### Webhook not being received

- Verify the webhook URL is registered in Didit's Business Console under your workflow
- Make sure your site is publicly reachable (not localhost or behind a firewall)
- Check your WordPress permalink settings — **pretty permalinks must be enabled**
- Check for a web application firewall (WAF) blocking POST requests from Didit's IPs
- Enable `WP_DEBUG` to see error logs: `define('WP_DEBUG', true); define('WP_DEBUG_LOG', true);`

### "Webhook secret not configured" error

The webhook secret is **mandatory**. If you see this error:
1. Go to **WPsigner → Integrations → Didit**
2. Paste your Webhook Secret from the Didit Business Console
3. Click **Save Settings**

### Signer status stuck on "pending"

This usually means the webhook was not received. Check:
1. Is the webhook URL registered in Didit?
2. Did Didit receive a non-200 response? Check the Didit Business Console → Webhook logs
3. Is the webhook secret correct?

WPsigner also queries the Didit API directly when the signer returns to the signing page (`Callback_Received` status), so even if the webhook is delayed, the status should update within a few seconds of the signer completing verification.

### "Invalid signature" webhook rejection

This means the webhook secret saved in WPsigner does not match the one in Didit. Resave the correct secret in **WPsigner → Integrations → Didit**.

### Didit KYC toggle reverts to OFF after saving

Ensure that you are saving the policy from **WPsigner → More → Security & Compliance**, not the Didit integration settings page. The credentials and the KYC policy are configured separately.

---

## Frequently Asked Questions

**Which countries and document types are supported?**

Didit supports government-issued IDs from 190+ countries, including passports, national identity cards, and driver's licenses.

**Does WPsigner store biometric data (photos, scans)?**

No. WPsigner **never** receives or stores the actual ID photos or selfie images. Only the verification decision metadata (face match score, document type, country, liveness result) is stored for the audit trail.

**Can signers retry if their verification is declined?**

Yes. A new verification session is automatically created when the signer clicks "Verify My Identity" again after a `Declined` or `Expired` status.

**Can I use Didit.me on a per-document basis instead of globally?**

Yes. Set the KYC policy to **Per document** in **Security & Compliance**, then enable KYC in the document's Review step. **Always** requires KYC for every signing request, and **Off** disables the gate.

**What happens if the Didit service is down?**

If the Didit API is unreachable when creating a session, the signer sees an error message and cannot proceed. WPsigner uses a 15-second timeout for API requests. If the webhook does not arrive but the signer completes verification, WPsigner will query the Didit API directly on the next status poll to retrieve the decision.

**Is Didit.me GDPR compliant?**

Yes. Didit.me processes verification data under its own privacy policy. WPsigner only stores the non-PII verification result metadata described above. Refer to [Didit's Privacy Policy](https://didit.me/privacy) for their data processing terms.

**What does "face match score" mean?**

The face match score (0–100%) represents the biometric confidence that the selfie matches the ID document photo. A score ≥ 70% is considered a passing match by WPsigner's audit trail logic.

---

## Related Documentation

- [Security & Compliance](/core-features/security-compliance/)
- [Audit Trails](/digital-identity/audit-trails/)
- [Legal Compliance](/compliance/)
- [Didit.me Official Documentation](https://docs.didit.me/)

---

# Report a Security Issue

> How to responsibly report security vulnerabilities in the WPsigner WordPress plugin.

edition: both
Edition: Lite + Pro
AI note: This page applies to Lite and Pro. Call out Lite limits (PDF only, max 2 signers, email OTP, local timestamp) when they apply. Do not invent Pro-only features.
HTML: https://docs.wpsigner.com/support/security/
Markdown: https://docs.wpsigner.com/md/support/security.md

If you believe you have found a security issue in WPsigner, please report it through our managed disclosure program. Do not post it publicly until we have had a chance to fix it.

WPsigner works with [Patchstack](https://patchstack.com/for-plugins/) to review reports, coordinate patches, and protect customers.

## Report a vulnerability

<iframe title="Report a security vulnerability in WPsigner" width="100%" height="700" style="max-width:500px;border:0;border-radius:12px;" src="https://patchstack.com/iframe/vendor?uuids=b983bd49-bd9c-4e59-9a6c-365e9be98cdc&theme=light" loading="lazy"></iframe>

[Open the reporting form in a new tab →](https://patchstack.com/database/vdp/wpsigner)

## What to include

- WPsigner version, plus WordPress and PHP versions
- Steps to reproduce the issue
- What an attacker could do if the issue were exploited
- Screenshots or a proof-of-concept, if you have one

## What happens next

1. Patchstack validates the report.
2. If it is confirmed, we receive the details and prepare a fix.
3. We release an update and coordinate disclosure when appropriate.

## Scope

This program covers the **WPsigner plugin** only. General product support is on the [support overview](/support/) page or [wpsigner.com/contact](https://wpsigner.com/contact/).

For the same policy on our main site, see [wpsigner.com/security](https://wpsigner.com/security/).
