▶ Watch it done once
Six minutes and 39 seconds, from the installer to a signature Adobe Reader accepts. Recorded on a clean machine, with narration and captions — every step below also has its own clip.
0 Before you start
Three things decide whether the rest of this guide goes smoothly.
| You need | Why |
|---|---|
| Windows 10/11 x64 and local administrator rights | OneSigner installs a Windows service. |
| A USB token holding a document- or code-signing certificate | The private key never leaves the token. OneSigner does not issue certificates. |
| Outbound HTTPS | Licence activation, the timestamp authority, and OCSP/CRL fetches for LTV. |
(Get-Process -Id $PID).SessionId — it must not be 0.
1 Download and verify OneSigner
Always check the installer before you run it. It takes ten seconds.
- Open Command Prompt or PowerShell in the folder you want the installer in and run this one line. It always fetches the latest release, no account needed:
powershell -ExecutionPolicy Bypass -NoProfile -Command "curl.exe -L --fail -o OneSigner-Setup.exe ((Invoke-RestMethod https://onesign.sg/portal/api/latest-version.php).url)"
Prefer the browser? Download it from onesign.sg/portal/trial.
- Verify the signature, then note the hash and the size:
powershell -ExecutionPolicy Bypass -NoProfile -Command "Get-AuthenticodeSignature .\OneSigner-Setup.exe | Format-List Status; (Get-AuthenticodeSignature .\OneSigner-Setup.exe).SignerCertificate | Format-List Subject,Issuer; Get-FileHash .\OneSigner-Setup.exe | Format-List Hash; (Get-Item .\OneSigner-Setup.exe).Length"
| Check | Expected |
|---|---|
| Status | Valid |
| Subject | Contains CN=One Sign Pte. Ltd. and O=One Sign Pte. Ltd. |
| Issuer | A GlobalSign code-signing CA |
Keep the SHA-256 and the size with your change record: they identify exactly which release you installed.
2 Install
A standard wizard. Accept the licence, confirm the folder, install.
| Installed | Where |
|---|---|
| Program files | C:\OneSigner\app\ |
| Configuration | C:\OneSigner\app\appsettings.json |
| Watched folders | C:\OneSigner\unsigned → C:\OneSigner\signed |
| Windows service | OneSignerService, listening on port 9440 |
For unattended rollout the installer accepts
/VERYSILENT /SUPPRESSMSGBOXES /NORESTART.
Watch steps 1 and 2 — download, verify, install · 0:40
C:\OneSigner unless you have a reason to change it.
3 Activate your licence
Every tab stays disabled until OneSigner is licensed.
- On first launch you get Activate OneSigner → Start your free 30-day trial.
- Enter your work email, full name, company and country, then click Email me a code.
- Take the 6-digit code from the email (subject Verify your email — OneSigner). It is valid for 30 minutes.
- Enter it and click Activate. Already bought? Use I already have a license key instead.
Confirm the service agrees:
(Invoke-WebRequest http://localhost:9440/ -UseBasicParsing).Content
# "license":{"status":"Valid","message":"License valid until ..."}
Watch step 3 — request the code and activate · 0:35
4 Install the driver for your token
Identify the token first, then install only the middleware that matches it.
Get-PnpDevice -PresentOnly | Where-Object { $_.Class -match 'SmartCard|USB' } |
Select-Object FriendlyName, InstanceId
certutil -scinfo -silent # shows the reader name and the card ATR
| USB VID | Token | Install |
|---|---|---|
1050 | YubiKey | YubiKey Smart Card Minidriver — winget install Yubico.YubiKeySmartCardMinidriver |
0529 | SafeNet / Aladdin eToken | SafeNet Authentication Client (Thales SAC 10.x) |
096E | Feitian / ePass | Feitian PKI middleware |
24DC | JaCarta | JaCarta client |
Then restart the smart-card stack and confirm the certificate reaches the Windows store:
Restart-Service SCardSvr -Force
Restart-Service CertPropSvc -Force
Get-ChildItem Cert:\CurrentUser\My | Select-Object Subject, Issuer, HasPrivateKey
HasPrivateKey : True.
If the list is empty, OneSigner's Certificate dropdown will be empty too — it is a driver problem,
not a OneSigner problem. Do not continue until this passes.
ykman piv info (winget install Yubico.YubiKeyManagerCLI).
On firmware below 5.3 the line Private key type: EMPTY is a reporting limitation,
not an empty slot. NTE_BAD_KEYSET from certutil means the minidriver is missing.
5 Configure the service — General tab
Port, API token and the folders the watcher uses.
- Leave Port at
9440unless it clashes with something. - Click Generate next to API Token if you will use the REST API.
- Confirm Upload Folder and Signed Folder.
- Click Save Settings.
AdminToken on the Tenants tab and save, so the installation never runs
on a value it did not choose for itself. Set the signing portal's administrator password the first time
you sign in, at /portal/profile, before the portal is reachable by anyone else — and
especially before step 12 puts it on the public internet.
Watch step 5 — port, API token and folders · 0:34
6 Create a PDF signing profile
Which certificate signs, where the signature lands, and which folders are watched.
- SigningEngine tab → + under Profiles.
- ID e.g.
profile_pdf, Name anything readable, Type PDF Signing. - Source folder
C:\OneSigner\unsigned, Signed folderC:\OneSigner\signed. - Certificate — pick your token certificate from the dropdown.
- Token PIN — the token's PIN.
- Position — Fixed position (page/X/Y), or Find by text to anchor the signature to a phrase, with Match page and Sign at.
- Timestamp — your CA's TSA, e.g.
http://timestamp.sectigo.com. - Tick LTV.
- Save, then Save All, and tick Signing Engine → Enabled.
C:\OneSigner\app\appsettings.json to SYSTEM and the local administrators: it carries the
settings for every profile, including the credentials the service needs to sign unattended. Treat every
backup copy the same way — off file shares, out of source control.
$cfg = 'C:\OneSigner\app\appsettings.json'
icacls $cfg /inheritance:r
icacls $cfg /grant 'SYSTEM:(R)' 'BUILTIN\Administrators:(F)'
Watch step 6, part 1 — create the signing profile · 0:46
Watch step 6, part 2 — the two switches · 0:40
7 Test sign, then verify properly
Do not trust a green tick in one application. Check the file itself.
- On the right of the SigningEngine tab set Sample PDF and click Test Sign.
- Open the signed file in Adobe Reader. The banner must read “Signed and all signatures are valid.”
- Then confirm the structure independently:
$t = [Text.Encoding]::GetEncoding(28591).GetString([IO.File]::ReadAllBytes("signed.pdf"))
[regex]::Match($t,'/SubFilter\s*/([A-Za-z0-9\.]+)').Groups[1].Value # ETSI.CAdES.detached
([regex]::Matches($t,'/DSS')).Count # 1 -> LTV data present
([regex]::Matches($t,'/OCSPs')).Count # 1 -> OCSP embedded
| What you should see | Meaning |
|---|---|
/ETSI.CAdES.detached | A PAdES signature, the modern standard |
/DSS, /Certs, /OCSPs, /VRI | LTV material embedded |
Unsigned attribute 1.2.840.113549.1.9.16.2.14 | RFC 3161 timestamp token |
Watch step 7 — verify the signature in Adobe Reader · 0:45
8 Sign automatically with a watched folder
The simplest production pattern: drop a file in, collect it signed.
Copy-Item .\invoice.pdf C:\OneSigner\unsigned\
Start-Sleep -Seconds 25
Get-ChildItem C:\OneSigner\signed
With the default 20-second poll the signed file appears in about ten seconds. The source file is consumed.
Watch steps 8 and 10 — watched folder, then the REST API · 0:51
9 Sign from the web portal
For people, rather than for systems.
- Open
http://localhost:9440/portaland sign in. - Pick the signing profile, drag PDFs in, click Sign Documents.
- Results appear under Signed files, and every operation is kept in Recent Signing History.
- Sign myself adds hand-drawn visual signatures; Management → Logs is the audit trail.
/portal/profile until you do. Make it long and random and keep it in a password manager —
not in a runbook, a script or a chat message. Then create per-person accounts at
/portal/admin rather than sharing one login.
10 Sign over the REST API
One call in, a signed PDF back.
curl -X POST "http://localhost:9440/api/upload?download=true" \
-H "Authorization: Bearer <TENANT_TOKEN>" \
-F "file=@contract.pdf" \
-o contract-signed.pdf
| Endpoint | Use |
|---|---|
POST /api/upload | Upload, and sign when ?download=true |
GET /api/list · GET /api/getfile | List and fetch files |
GET /api/signing/status | Signing engine status (admin) |
GET /api/license/hardware-id | This machine's hardware ID |
401 Invalid token until you
Restart-Service OneSignerService -Force. And a response containing
"signing": null means no signing profile is linked to that tenant.Authorization: Bearer <TENANT_TOKEN>, Authorization: <TENANT_TOKEN> and
?token=<TENANT_TOKEN> on the query string are all accepted. An X-Api-Token
or X-Tenant-Token header returns 401.11 Code signing and the command line
For installers, executables and CI/CD.
- Create a second profile with Type = Code Signing and select the code-signing certificate.
- Sign locally with
OneSignTool.exeinC:\OneSigner\app\. - For remote or build-agent signing use the AKV Proxy profile and
OneSignTool -kvu <server URL> -kva <partner code> -kvc <CertName>.
12 Publish a public HTTPS address
Needed for the portal, partner packages and remote signing. No open ports required.
- Web Server tab → Download cloudflared (one-time, ~52 MB).
- Sign in at onesign.sg/portal/login → My Licenses → Custom Domain.
- Choose your subdomain and the local port (must match the port in step 5), then create it.
- Copy the tunnel token back into Tunnel Token, tick Enable Cloudflare Tunnel, set Public URL, save, and restart the service.
cloudflared.exe tunnel --no-autoupdate run --token <TOKEN> prints
“Provided Tunnel token is not valid.” Copy the current token from My Licenses → Custom
Domain, paste it back in, save and restart. Nothing needs reinstalling.Watch step 12 — publish a public HTTPS address · 1:11
13 Teams, tenants and branding
Separate who signs what, and make the portal look like yours.
- Tenants tab → + Add for each business unit or customer: its own token and folders.
- Link a signing profile to the tenant, or its uploads will be stored but never signed.
- Give each person their own portal account at
/portal/admin. - Portal → Settings → Branding sets the name, logo, colour, support email and email footer.
Watch step 13 — add a tenant and link its profile · 0:37
? Troubleshooting
| Symptom | Cause and fix |
|---|---|
| Certificate dropdown is empty | Token driver missing. Redo step 4 and confirm HasPrivateKey : True. |
NTE_BAD_KEYSET from certutil -scinfo | Windows cannot read the token's slot — install the vendor minidriver. |
401 Invalid token on the API | Restart the service after adding a tenant. Send the token as Authorization: Bearer …, a bare Authorization header or ?token=; X-Api-Token is ignored. |
"signing": null in the response | No signing profile is linked to that tenant. |
| Ghostscript not found | Only affects the Preview pane. Signing works without it. |
| Files pile up in the watched folder | SigningEngine → Enabled is off, or that one file is malformed. See step 6. |
Public address returns 530 | The tunnel token was reissued. Copy the current one from My Licenses → Custom Domain. |
| Token invisible when run from a service or SSH | Session 0 has no smart-card access. Use an interactive session. |
| Signature “valid now, unknown later” | Timestamp or LTV not set on the profile — see step 6. |
| PIN rejected | Stop. Tokens lock after a few attempts and need the PUK or a reset. |
✓ All done — what next?
- Restrict NTFS permissions on
C:\OneSigner\app\appsettings.json— it carries the settings and credentials for every profile. - Back up that file; it is your whole configuration.
- Set a calendar reminder for your certificate's expiry date.
- Confirm the admin token and the portal password are both values you chose yourself.
Questions: support@onesign.sg · Hotline +65 3107 1270