Docs · Integration

Run GOVP on your own domain.

Take GOVP to production: publish your identity, keep signing keys where they belong, sign with a KMS/HSM, anchor time independently and harden the public surface. Config below reflects the reference WordPress implementation.


1 · Publish identity

Serve your .well-known endpoints

GOVP publishes your domain identity, a discovery index and each record under .well-known. The one host-dependent step is making sure those paths reach the application rather than being served as static files.

GET /.well-known/govp.txt # domain identity (public key + metadata) GET /.well-known/govp/index.json # discovery index of published records GET /.well-known/govp/<id>.govp # a single, self-contained record
# Nginx — route the GOVP paths to the app, before any static .well-known block location ^~ /.well-known/govp { try_files $uri $uri/ /index.php?$args; }
# Apache — ensure nothing short-circuits the path before the app's rules RewriteCond %{REQUEST_URI} ^/\.well-known/govp RewriteRule ^ index.php [L]

If the responses return GOVP content and not a static 404, routing is correct. If root detection is unreliable (multisite, symlinks, atypical DOCUMENT_ROOT), pin the directory explicitly with GOVP_WELL_KNOWN_DIR.

2 · Key custody

Keep the signing key out of the web root

The signing key is the whole game. In a production environment, if the key sits under the web root the reference implementation blocks issuing with an actionable error — verification keeps working. Resolve it by pointing the key at a safe path.

# wp-config.php — store the key outside the webroot (recommended) define('GOVP_KEY_DIR', '/var/lib/govp-keys'); # only if you accept the risk and want it under uploads/ define('GOVP_ALLOW_WEBROOT_KEY', true);

Field and mobile verifiers only verify, never sign. Signing belongs on a controlled host — or better, off-box entirely (next section).

3 · External signing

Sign with a KMS, HSM or Vault

For high-value signing, the private key never has to touch the application. Declare the public key and hook the signing operation to your KMS/HSM/Vault or a signing endpoint. The core verifies that the returned signature matches the declared public key before using it — and when an external signer is present, no local key is used or required.

# declare the Ed25519 public key (base64) define('GOVP_EXTERNAL_PUBKEY', '<base64 of the Ed25519 public key>'); # return the 64-byte signature produced by your KMS/HSM add_filter('govp_external_sign', function($null, $msg, $pub){ return my_kms_sign_ed25519($msg); # core checks it against GOVP_EXTERNAL_PUBKEY }, 10, 3);
4 · Time anchoring

Make the fixation time independently provable

Under GOVP-BASIC the Generated-At time is issuer-asserted. When ordering-in-time can be contested, choose a stronger profile so even the issuer cannot move the time.

GOVP-BASICIntegrity & authorship only; time is issuer-asserted. Use when timing is not disputed.
GOVP-RFC3161Bind the fixation to an RFC 3161 trusted timestamp from an independent TSA.
GOVP-QTSPAnchor with an eIDAS qualified timestamp for the strongest, legally-recognized time evidence in the EU.

Independent witnesses (the mesh) provide a further, registry-free way to anchor ordering. See the time profiles and mesh in the spec.

5 · Hardening

A safe public surface by default

Evidence is meant to be verified from anywhere, so the read endpoints are deliberately open — but the outbound and write paths are locked down.

Outbound HTTPAll external calls (verify, discovery, witnesses, TSA) go through one guarded client: public IPs only, no redirects, IP pinning against rebinding, scheme/port allowlist.
Public read + CORSRead endpoints (records, badge, .well-known) send Access-Control-Allow-Origin: * on purpose — evidence is public and must verify from any origin. No secrets are exposed.
Rate limitingPer-IP limits on public endpoints, configurable and disableable.
Paginated APIGET /records?page=1&per_page=50 (max 200), with total/pages headers.
Stable asset IDsDefault asset id is stable (post-<ID>); renaming a URL does not change identity. Opt into slug mode if you prefer.
6 · Availability

Durability is a copy that survives

Verification does not need the issuer to stay online — but it does need a surviving copy of the record. Don't rely on a single host holding issuance, storage, publication and verification at once.

  • Export signed bundles of your records and keep an external mirror.
  • Treat the local transparency log as a journal, not public transparency — a compromised admin could rewrite it; strong transparency needs external anchoring.
  • Publish records at your domain and hand copies to the parties who rely on them.
← Gemacode Research