Signing and Encrypting Documents in LotusScript: Sign, Encrypt, and the Save-Order Rule
Two of Domino’s oldest security features are one method call each — and both fail quietly if you get the sequence wrong. Sign attaches a cryptographic signature proving who wrote the document; Encrypt scrambles chosen items so only key-holders can read them. The traps aren’t in the crypto — they’re in when the change hits disk and whose identity does the work.
TL;DR
doc.Signsigns with the current user’s (or signer’s) ID. “If you want the signature to be saved, you must call the Save method after signing” — Sign alone doesn’t persist.- In a server agent, signing needs permission: the signer must be listed in “Run unrestricted methods and operations” in the server document, or you get error 4165.
- Encryption is per-item and opt-in: set
item.IsEncrypted = Trueon each item you want protected, then calldoc.Encrypt, thendoc.Save. Items you don’t flag “remain visible to any user, even if the user does not have the proper encryption key.” - Order is mandatory: flag items →
Encrypt→Save. “The encrypted document is not written to disk until you call the Save method.” - With no keys set,
Encryptuses the user’s public key (only they can decrypt). SetEncryptionKeysto one or more named secret keys to share access. - Mailing is separate:
EncryptOnSend/SignOnSendact only when the document is mailed and have “no effect on whether a document is encrypted when saved to a database.” When mailing,EncryptionKeysis ignored — recipient public keys are used instead.
Signing
Sign takes no parameters — it signs with the identity running the code, and you must save to keep it:
Dim session As New NotesSessionDim db As NotesDatabaseDim doc As NotesDocumentSet db = session.CurrentDatabaseSet doc = New NotesDocument(db)doc.Form = "Main Topic"doc.Subject = "A signed document"Call doc.SignCall doc.Save(False, True)Print "Signed by: " & doc.Signer & ", verified by: " & doc.VerifierThat’s the official example. After signing, doc.IsSigned is True, doc.Signer names who signed, and doc.Verifier names the certificate that vouches for them (both empty if unsigned or the signer isn’t trusted).
The identity question matters most in agents. Sign uses “the current user’s Notes ID” — and in a background agent, who that is depends on how the session was obtained (a plain NotesSession runs as the agent signer; sessionAsSigner is the mechanism for signing as the design element’s signer). Either way the documented hard requirement is permission: a server-based agent that signs must have its signer in the server’s “Run unrestricted methods and operations” list, or it fails with lsERR_NOTES_SIGN_NOPERM (4165).
Encrypting
Encryption is opt-in per item and has a strict order. You flag the items to protect, call Encrypt, then Save — this is the official pattern for a named secret key:
Dim doc As NotesDocumentDim itemA As NotesItemDim itemB As NotesItem'...set value of doc...Set itemA = doc.GetFirstItem("Subject")Set itemB = doc.GetFirstItem("Body")itemA.IsEncrypted = TrueitemB.IsEncrypted = Truedoc.EncryptionKeys = "Top Secret"Call doc.EncryptCall doc.Save(True, True)Three rules are doing the work here. First, only flagged items are encrypted — anything without IsEncrypted = True stays readable by anyone, so encrypting “the document” really means encrypting the items you marked. Second, setting the flag does nothing on its own: “the item is not actually encrypted until you call the Encrypt method on the parent NotesDocument.” Third, Encrypt doesn’t touch disk — “the encrypted document is not written to disk until you call the Save method.” Miss the Save and you’ve encrypted nothing.
The EncryptionKeys property chooses who can decrypt. With no keys set, Encrypt uses the current user’s public key — only they can ever read it back, which is rarely what you want for shared data. Set one or more named secret keys (which recipients must hold in their ID) to share access. For server agents encrypting on someone else’s behalf, the Encrypt(userid) / Encrypt(idfile, password) overloads let you encrypt with a specific identity’s keys, typically fetched via NotesIDVault.
Mailing is a different mechanism
The most common confusion: EncryptOnSend and SignOnSend are not the same as Encrypt/Sign. They apply only when the document is mailed, and the docs are blunt that EncryptOnSend “has no effect on whether a document is encrypted when saved to a database.” Two consequences worth internalising:
- When mailing,
EncryptionKeysis ignored — Domino “looks for the public key of each recipient in the Domino Directory” instead. And if it can’t find a recipient’s public key, it “sends an unencrypted copy of the document to that recipient” — a silent downgrade to plaintext that’s easy to miss. - To protect the stored copy in a database, use
Encrypt; to protect the mailed copy in transit, useEncryptOnSend. They solve different problems and you sometimes want both.
What about Java and SSJS?
| LotusScript | Java | SSJS / XPages |
|---|---|---|
doc.Sign / doc.Encrypt | doc.sign() / doc.encrypt() | document.sign() / document.encrypt() |
doc.EncryptionKeys | doc.getEncryptionKeys() / setEncryptionKeys() | same, camelCase |
doc.IsSigned / IsEncrypted / Signer | doc.isSigned() / isEncrypted() / getSigner() | same |
The lotus.domino.Document surface mirrors the LotusScript one across Java and SSJS, and every caveat carries over: flag-items-then-encrypt-then-save, the server permission for signing agents, and the strict separation between database-copy encryption (encrypt) and mail-time encryption (encryptOnSend).