Ga naar hoofdinhoud

Document signing — administrator guide

This guide walks a Nextcloud administrator through enabling, configuring and operating DocuDesk's signing workflow. It is the operational counterpart to the end-user Digital Signing Integration document and to the OpenSpec change document-signing.

The signing feature is fully implemented in lib/Service/SigningService and the two SigningProviderInterface implementations (NativeSigningProvider, ValidSignProvider); this guide describes the admin surface only — endpoint reference lives in appinfo/openapi.json.

1. Prerequisites

  • DocuDesk is installed and enabled (occ app:enable docudesk).
  • OpenRegister is installed and the DocuDesk register/schema set has been imported (DocuDesk's repair step InitializeRegister handles this on first enable).
  • A user account that is a member of the admin group (Nextcloud's IGroupManager::isAdmin() test is used by the controllers).

2. Active provider — signing_provider

The active signing provider is resolved at request time by SigningProviderFactory::getProvider() from the IAppConfig key docudesk.signing_provider. Two providers ship in-app:

ValueProvider classWhen to choose
native (default)NativeSigningProviderSelf-contained signing with a Nextcloud-resident audit trail; no external dependency.
validsignValidSignProviderDelegate to ValidSign for AdES / QES levels; required for the eIDAS levels above SES.

Switch with:

occ config:app:set docudesk signing_provider --value=validsign

Setting any other value falls back to native (defensive, matches the factory default).

3. Default signature level — signing_default_level

Sets the eIDAS level applied to new signing requests that do not specify one.

ValueMeaningProvider support
SES (default)Simple electronic signaturenative, validsign
AdESAdvanced electronic signaturevalidsign only
QESQualified electronic signaturevalidsign only
occ config:app:set docudesk signing_default_level --value=AdES

If the configured provider does not support the requested level, the SigningService::createSigningRequest() flow returns a 422-shaped error with a machine-readable code so the caller can surface a precise message.

4. Signing-request expiry — signing_request_expiry_days

signing_request_expiry_days (default 30) controls how long an open signing request stays valid. The background job SigningExpirationJob (declared in appinfo/info.xml under <background-jobs>) walks open requests once a day and transitions every request whose expiresAt has passed into the expired lifecycle state.

occ config:app:set docudesk signing_request_expiry_days --value=14

The value is read every time a request is created — no service restart needed.

5. Register / schema bindings

SigningService writes four object types into OpenRegister; each pair is configured with its register slug + schema slug. The repair step pre-populates these on first enable; admins only override them when running custom OR registers.

Object*_register key*_schema key
Signing requestdocudesk.signingRequest_registerdocudesk.signingRequest_schema
Signer recorddocudesk.signerRecord_registerdocudesk.signerRecord_schema
Signing sessiondocudesk.signingSession_registerdocudesk.signingSession_schema
Audit entrydocudesk.signingAuditEntry_registerdocudesk.signingAuditEntry_schema

The values are register/schema slugs (e.g. document and signingRequest), not numeric IDs.

6. ValidSign credentials

When signing_provider = validsign, the following keys MUST also be set:

KeyPurpose
docudesk.validsign_base_urlAPI base URL of the ValidSign tenant.
docudesk.validsign_api_tokenBearer token used in Authorization headers.
docudesk.validsign_webhook_secretHMAC secret used to verify callback signatures.

Use occ config:app:set with --sensitive for the token and secret so they are never returned by the admin settings API.

7. Operational concerns

  • Audit trail — every state-changing operation (createSigningRequest, signRequest, cancelRequest, expiration sweep) emits a signingAuditEntry row with x-openregister-archival = P10Y. Operators should never delete these objects directly; archival is enforced by OpenRegister.
  • Notifications — DocuDesk emits notifications via the canonical x-openregister-notifications dialect (SigningRequestNotifier, SigningSessionNotifier). Tenants can override per-event recipients in lib/Settings/docudesk_register.json and re-import.
  • Background job verification — confirm the expiry sweep runs with occ background-job:list | grep SigningExpiration and the standard NC cron. A missing entry means the repair step did not run (re-enable the app to re-trigger it).

8. Troubleshooting

SymptomLikely causeFix
"Provider not available" on createsigning_provider = validsign with empty validsign_api_tokenSet the token (see §6) or fall back to native.
Requests stay pending after expiresAtSigningExpirationJob not scheduledEnsure NC cron runs at least once a day; verify background-jobs block in appinfo/info.xml was picked up by re-running occ app:enable docudesk.
Signed PDF rejected on verificationProvider mismatch (signed by ValidSign, verified by native)Verify with the same provider used to sign, or re-issue a request using the desired provider.

9. Cross-references

  • ADR-022 (apps-consume-or-abstractions) — explains why DocuDesk's signing pipeline is built on OpenRegister objects rather than a private table.
  • OpenSpec document-signing — feature-level requirements and scenarios.
  • OpenSpec migrate-signing-audit-to-or-audit — current shape of the audit pipeline; this guide reflects the post-migration state.
  • OpenSpec migrate-signing-to-or-approval-workflow — describes the planned lifecycle-driven implementation; admin keys above stay backward-compatible.