Setup guide

Set up OneSigner, step by step

From a clean Windows machine to a digitally signed PDF that Adobe Reader reports as “Signed and all signatures are valid”, with a timestamp and long-term validation data embedded. Tick each step off as you go: your progress is remembered on this device.

~30 minutesWindows 10 / 11 x64USB token required6:39 video walkthrough

Guide published · last reviewed by the One Sign engineering team.

0 of 14 steps

▶ 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 needWhy
Windows 10/11 x64 and local administrator rightsOneSigner installs a Windows service.
A USB token holding a document- or code-signing certificateThe private key never leaves the token. OneSigner does not issue certificates.
Outbound HTTPSLicence activation, the timestamp authority, and OCSP/CRL fetches for LTV.
The single most common failure OneSigner can only show a certificate that Windows itself can already see. If your token's driver is missing, the Certificate dropdown will simply be empty and nothing else will work. Do step 4 before you create any profile.
Working remotely? Smart-card access and the configuration tool need an interactive desktop session. Over a service, scheduled task or SSH you land in Session 0, where the token is invisible. Check with (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.

  1. 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.

  1. 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"
CheckExpected
StatusValid
SubjectContains CN=One Sign Pte. Ltd. and O=One Sign Pte. Ltd.
IssuerA GlobalSign code-signing CA

Keep the SHA-256 and the size with your change record: they identify exactly which release you installed.

If the status is not Valid or the signer is anyone else stop and re-download. Do not run the installer.

2 Install

A standard wizard. Accept the licence, confirm the folder, install.

InstalledWhere
Program filesC:\OneSigner\app\
ConfigurationC:\OneSigner\app\appsettings.json
Watched foldersC:\OneSigner\unsigned → C:\OneSigner\signed
Windows serviceOneSignerService, listening on port 9440

For unattended rollout the installer accepts /VERYSILENT /SUPPRESSMSGBOXES /NORESTART.

Watch steps 1 and 2 — download, verify, install · 0:40
The OneSigner setup wizard, licence agreement page
Accept the licence agreement and click Next.
The setup wizard confirming the destination folder
Leave the destination at C:\OneSigner unless you have a reason to change it.
The setup wizard reporting that installation has finished
Installation finished — the service is registered and running.

3 Activate your licence

Every tab stays disabled until OneSigner is licensed.

  1. On first launch you get Activate OneSigner → Start your free 30-day trial.
  2. Enter your work email, full name, company and country, then click Email me a code.
  3. Take the 6-digit code from the email (subject Verify your email — OneSigner). It is valid for 30 minutes.
  4. 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 ..."}
One trial per machine and per email The key is bound to this machine's hardware ID. Activate on the machine that will actually do the signing.
Watch step 3 — request the code and activate · 0:35
The activation dialog with the trial registration form
First launch: the trial form, with every other tab disabled behind it.
The six-digit verification code entered in the activation dialog
The six-digit code from the e-mail, entered before it expires.
The configuration window with all tabs enabled after activation
Activated — the tabs unlock and the service reports Running.

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 VIDTokenInstall
1050YubiKeyYubiKey Smart Card Minidriver — winget install Yubico.YubiKeySmartCardMinidriver
0529SafeNet / Aladdin eTokenSafeNet Authentication Client (Thales SAC 10.x)
096EFeitian / ePassFeitian PKI middleware
24DCJaCartaJaCarta 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
This is the gate You must see your certificate with 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.
YubiKey users The certificate normally lives in PIV slot 9A. Inspect it directly with 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.

  1. Leave Port at 9440 unless it clashes with something.
  2. Click Generate next to API Token if you will use the REST API.
  3. Confirm Upload Folder and Signed Folder.
  4. Click Save Settings.
Set the two operator secrets now Generate the 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
The General tab of the configuration window
The General tab. The API token is masked here — yours is a secret, treat it like one.

6 Create a PDF signing profile

Which certificate signs, where the signature lands, and which folders are watched.

  1. SigningEngine tab → + under Profiles.
  2. ID e.g. profile_pdf, Name anything readable, Type PDF Signing.
  3. Source folder C:\OneSigner\unsigned, Signed folder C:\OneSigner\signed.
  4. Certificate — pick your token certificate from the dropdown.
  5. Token PIN — the token's PIN.
  6. Position — Fixed position (page/X/Y), or Find by text to anchor the signature to a phrase, with Match page and Sign at.
  7. Timestamp — your CA's TSA, e.g. http://timestamp.sectigo.com.
  8. Tick LTV.
  9. Save, then Save All, and tick Signing Engine → Enabled.
Always set Timestamp and LTV The timestamp proves when you signed, so the signature stays valid after the certificate expires. LTV embeds the certificate chain and OCSP responses, so it can still be validated years later offline. Without them a signature degrades to “valid today, unverifiable later”.
Two switches, not one Enabled at the top of the SigningEngine tab controls the watcher itself, and it is off on a fresh install. On, beside the profile ID, controls that one profile. With On ticked and Enabled clear everything looks right — the profile saves, the certificate binds, Test Sign works — but nothing dropped into the watched folder is ever picked up, and no error is written anywhere. If folder watch “does not work”, check this first.
Careful with the PIN Most tokens lock after a few wrong attempts — do not retry a PIN you are unsure of. Restrict 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
A completed PDF signing profile on the SigningEngine tab
A finished PDF profile: certificate bound, timestamp URL set, LTV ticked.

7 Test sign, then verify properly

Do not trust a green tick in one application. Check the file itself.

  1. On the right of the SigningEngine tab set Sample PDF and click Test Sign.
  2. Open the signed file in Adobe Reader. The banner must read “Signed and all signatures are valid.”
  3. 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 seeMeaning
/ETSI.CAdES.detachedA PAdES signature, the modern standard
/DSS, /Certs, /OCSPs, /VRILTV material embedded
Unsigned attribute 1.2.840.113549.1.9.16.2.14RFC 3161 timestamp token
Preview pane empty? The Preview button renders thumbnails with Ghostscript and will say “Ghostscript not found. Install BulkSigner or Ghostscript.” if it is not installed. That is a Preview dependency only: signing — from the GUI, the watched folder or the REST API — does not use it.
Watch step 7 — verify the signature in Adobe Reader · 0:45
Adobe Reader showing the green banner for a valid signature
What you are aiming for: Signed and all signatures are valid.

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.

Nothing happened at all? Go back to step 6 and check the Enabled switch. Note also that a malformed PDF is left sitting in the folder with no error written anywhere — if one file never moves while others do, suspect the file, not the service.
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.

  1. Open http://localhost:9440/portal and sign in.
  2. Pick the signing profile, drag PDFs in, click Sign Documents.
  3. Results appear under Signed files, and every operation is kept in Recent Signing History.
  4. Sign myself adds hand-drawn visual signatures; Management → Logs is the audit trail.
Set the administrator password first The portal asks you to set it the first time you sign in, and keeps you on /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.
The portal asking for a new administrator password at first sign-in
First sign-in: nothing else in the portal opens until the password is changed.
The signing portal after signing in
The portal: pick a profile, drop PDFs in, collect them from Signed files.

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
EndpointUse
POST /api/uploadUpload, and sign when ?download=true
GET /api/list · GET /api/getfileList and fetch files
GET /api/signing/statusSigning engine status (admin)
GET /api/license/hardware-idThis machine's hardware ID
Two things that look like bugs A newly created tenant returns 401 Invalid token until you Restart-Service OneSignerService -Force. And a response containing "signing": null means no signing profile is linked to that tenant.
Three auth forms work, two plausible ones do not 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.

  1. Create a second profile with Type = Code Signing and select the code-signing certificate.
  2. Sign locally with OneSignTool.exe in C:\OneSigner\app\.
  3. For remote or build-agent signing use the AKV Proxy profile and OneSignTool -kvu <server URL> -kva <partner code> -kvc <CertName>.
Never give the AdminToken to a partner or a build agent. Issue a partner code for remote signing instead, and review which certificates it can reach.

12 Publish a public HTTPS address

Needed for the portal, partner packages and remote signing. No open ports required.

  1. Web Server tab → Download cloudflared (one-time, ~52 MB).
  2. Sign in at onesign.sg/portal/login → My Licenses → Custom Domain.
  3. Choose your subdomain and the local port (must match the port in step 5), then create it.
  4. Copy the tunnel token back into Tunnel Token, tick Enable Cloudflare Tunnel, set Public URL, save, and restart the service.
The subdomain can only be chosen once Changing it afterwards needs support. Names that look like our own brand are reserved and will be rejected — a rejected attempt does not use up your one choice.
Prefer your own domain and certificate? Use Option B — Direct HTTPS on the same tab.
Re-check the portal password before this goes live.
Public address gone dark with HTTP 530? Check the tunnel token before anything else. Reissuing it on Cloudflare's side silently invalidates the copy the service holds: signing keeps working locally, the local port keeps answering, and only the public address dies. Run the connector by hand to see the reason the service never logs — 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
The Web Server tab with the Cloudflare tunnel enabled
The Web Server tab with the tunnel enabled and the public URL set.

13 Teams, tenants and branding

Separate who signs what, and make the portal look like yours.

  1. Tenants tab → + Add for each business unit or customer: its own token and folders.
  2. Link a signing profile to the tenant, or its uploads will be stored but never signed.
  3. Give each person their own portal account at /portal/admin.
  4. Portal → Settings → Branding sets the name, logo, colour, support email and email footer.
Branding is per installation, not per tenant — one brand per OneSigner install.
Watch step 13 — add a tenant and link its profile · 0:37
The Tenants tab after a tenant has been created
A tenant with its own token and folders. Restart the service before you use that token.

? Troubleshooting

SymptomCause and fix
Certificate dropdown is emptyToken driver missing. Redo step 4 and confirm HasPrivateKey : True.
NTE_BAD_KEYSET from certutil -scinfoWindows cannot read the token's slot — install the vendor minidriver.
401 Invalid token on the APIRestart 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 responseNo signing profile is linked to that tenant.
Ghostscript not foundOnly affects the Preview pane. Signing works without it.
Files pile up in the watched folderSigningEngine → Enabled is off, or that one file is malformed. See step 6.
Public address returns 530The tunnel token was reissued. Copy the current one from My Licenses → Custom Domain.
Token invisible when run from a service or SSHSession 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 rejectedStop. 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