Hi all,
another hobby project from my repository: an RFC 3161 Timestamp Authority (TSA) packaged for NethServer 8, based on the sigstore timestamp-server.
What it does
It lets you issue and verify trusted timestamp tokens for documents and signatures — e.g. from LibreSign, JSignPdf or openssl ts. If you have ever signed a PDF and had Adobe Acrobat reject the timestamp because only the local server clock was used, this is the piece that fixes it: a proper RFC 3161 token, signed by a dedicated timestamping certificate.
Why I built it
I ran into exactly that problem with LibreSign on Nextcloud: signatures carried only a local signing_time instead of an embedded RFC 3161 token, so Acrobat flagged them as untrusted. Rather than depend on a public TSA with limited stamp capability or a paid TSA service, I wanted a small, self-hosted one on my own cluster.
Why self-host it?
- Small and simple. A single distroless, rootless container (UID 65532), bound to
127.0.0.1and published through the node’s Traefik. - Your data stays on your server. Timestamp queries never leave your infrastructure.
- Standard clients. Works with anything that speaks RFC 3161 — LibreSign, JSignPdf,
openssl ts.
NS8 integration
The module runs the sigstore timestamp-server image and publishes it on a host name of your choice via Traefik, with optional Let’s Encrypt and HTTP→HTTPS redirect.
Endpoints under the configured host name:
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/timestamp |
Submit an application/timestamp-query |
| GET | /api/v1/timestamp/certchain |
Download the signing certificate chain |
| GET | /ping |
Health check |
Client timestamp URL: https://<fqdn>/api/v1/timestamp
Two separate certificates — this is the part to understand:
- HTTPS transport cert (Let’s Encrypt): the ordinary TLS cert Traefik serves, renewed automatically. It can not be used for signing — RFC 3161 requires the critical
extendedKeyUsage = timeStamping, which public CAs never issue. - RFC 3161 signing cert (self-signed, long-lived): generated on first configuration as a dedicated EC P-384 chain — Root CA ~30 years, leaf ~25 years, leaf key stored as an AES-256 encrypted PKCS#8. The chain is embedded in every token. Existing certificates are never overwritten on reconfigure; rotation is an explicit action.
The Certificate page lets you view the current signer (subject, valid-until, SHA-256 fingerprint), download the chain, run a self test (issues a real token and verifies it), rotate (archives the old chain, generates a new one), or upload an externally obtained timestamping certificate (validated for the timeStamping EKU before anything is replaced).
Installation
On a NethServer 8 node:
add-module ghcr.io/tebbiworld/tsa:latest 1
Then open the module UI, set the host name (FQDN), and optionally enable Let’s Encrypt and HTTP→HTTPS redirect. On the first save the module generates its signing chain and starts the server.
Trust & evidentiary value
Clients that verify your tokens must trust the Root CA — download the chain from /api/v1/timestamp/certchain and import the Root into the verifying client (e.g. Adobe Acrobat’s Trusted Certificates, or via openssl ts -verify -CAfile).
Be aware: a self-operated TSA is fine for internal and technical use, but against third parties its tokens carry limited legal weight compared to an accredited, audited provider. If you need qualified/eIDAS-grade timestamps, obtain a commercial timestamping certificate and install it via Upload certificate.
Back up the Root CA private key offline — it is the trust anchor of your whole TSA.
Important disclaimer
This is a private hobby project, built for my own needs and shared as-is. No warranty, no guaranteed support, use at your own risk. It is an unofficial, community-built package, not affiliated with or endorsed by the sigstore project. The module pulls the upstream sigstore timestamp-server at runtime; the module’s own code is GPL-3.0-or-later.
Feedback and bug reports are welcome via GitHub issues, but please don’t expect enterprise-level maintenance.
Have fun with it!