Security
How WorkVigil protects your company’s data
WorkVigil holds the record of who did what, with the evidence. This page sets out the controls that are built into the product: how one customer’s data is kept apart from another’s, how people sign in, and what is recorded. It describes what the product does and makes no certification claim.
Seven controls, built in
Each one is part of how the product stores and serves data, so it applies to every customer on every plan. Follow a card for the detail.
- The database itself returns only the rows of the workspace a request belongs to.
Passwords hashed with Argon2id
A password is stored only as a hash. Nobody can read it back.Emails and phones encrypted
Stored as AES-256-GCM ciphertext and looked up by a keyed hash.A permanent audit trail
Changes, sign-ins and exports are recorded, and the application cannot edit the record.Roles and permissions
Nine standard roles, custom roles, and a check on the server for every request.Sessions that can be revoked
Being signed in is a record on the server, and the server can end it.Files stored privately
Evidence and documents have no public address. Every download is checked.
How each control works
Written for the person who has to answer for it: what is enforced, and where.
Each workspace’s data is isolated in the database
A workspace is one customer: a company, or a group that runs several companies in it. The separation between two workspaces is enforced by PostgreSQL row-level security, not only by the application’s code.
- Every table that holds a workspace’s work (tasks, projects, comments, evidence, documents, approvals, time entries and the rest) carries a row-level security policy. A query sees the rows of one workspace and no others.
- Every database transaction of a request first declares the workspace and the signed-in person. Without that declaration the database returns none of those rows and refuses to write to them.
- The workspace and the person come from the session the server issued at sign-in and verifies on every request. They are never read from a field of the request.
- The application connects with a restricted database login. It refuses to start if that login is a superuser, can bypass row-level security or owns the protected tables.
- The companies of a group that share one workspace are kept apart by roles and visibility — which tasks and projects a person sees, checked by the server on every request — not by the database’s row-level security.
Row-level security separates one workspace’s requests from another’s. It does not replace the protection of the servers and of the database login, which belongs to the hosting.
Passwords are hashed with Argon2id
WorkVigil stores a password only as an Argon2id hash. It cannot be read back by an administrator of your company, or by us.
- Argon2id with 19 MiB of memory and two passes for every password. A new password needs at least ten characters.
- A failed sign-in gives the same answer after the same amount of work, whether the address is unknown or the password is wrong. The sign-in screen does not reveal who has an account.
- Requests to sign in, to reset a password or to accept an invitation are limited to ten a minute from one network address.
- Invitations and password resets use a one-time code of ten characters, sent to the person’s own address and stored only as a hash. A reset code expires after 15 minutes, and five wrong attempts use a code up.
- Resetting a password ends every session of that person. Changing it ends all their other sessions.
Email addresses and phone numbers are encrypted at rest
The two details that identify a person outside your company are not stored in readable form.
- A member’s email address and phone number are stored as AES-256-GCM ciphertext.
- To find a person by their address the database compares a keyed hash of it (HMAC-SHA-256). The readable address is not stored beside it.
- The encryption key and the hashing key are held by the application server, outside the database. A copy of the database alone does not reveal the addresses.
- One consequence you will notice: searching for a member by email matches the whole address only.
This is encryption of these two fields. Task titles, comments and files are protected by the isolation and the permissions described on this page, not by a key of their own.
A permanent audit trail
Who changed what, when and from where is recorded by the database in the same step as the change.
- A change to a record is written to the audit log by a database trigger, inside the transaction that makes the change: the person, the time, the action, the request and the network address it came from, and the values before and after. Secrets such as password hashes are redacted.
- Sign-ins, failed sign-ins, sign-outs, password resets and changes, invitations, sessions ended by an administrator and exports are recorded as security events.
- The application can read the audit log and has no permission to change or delete an entry. Entries are added only by the database’s own functions.
- Routine clean-up removes expired sessions, expired one-time codes and events that are older than the retention period of the activity feed. It does not touch the audit trail.
- In the product, the Audit Trail page is open to the Administrator and Auditor roles. A task’s own Activity tab shows its history to everyone who can see the task.
- The application’s database login has no permission to delete a task, a project, a comment, a piece of evidence, a document or a time entry. Taking one away can only mean archiving it, so the record a decision was based on stays available.
Roles and permissions
People see and do what their role allows. The server decides; the screen only follows.
- Nine standard roles: Administrator, CXO, Business Head, Department Head, Manager, Team Lead, Employee, Field Executive and Auditor. A company can copy any of them into a custom role and change what it may do.
- A permission is an action on a kind of record, such as approving a task or exporting a report. Every request is checked against the caller’s permissions on the server. Hiding a button is never the control.
- Which tasks and projects a person can see is scoped as well: everything, those of their own departments and projects, or only the work they are assigned to, manage, created, follow or approve.
- Approval requests and escalations go to the holders of a role in the task’s own company or department, not to everyone who holds that role.
- Deactivating a user ends their sessions at once.
- A change to a role’s permissions is itself written to the audit trail.
Sessions that can be revoked
A sign-in creates a session on the server. Ending that session signs the person out, wherever their browser is.
- The browser holds a short-lived access token in memory (15 minutes by default) and a refresh cookie that scripts cannot read: HttpOnly, SameSite=Strict, sent over HTTPS and only to the sign-in routes.
- The secret in that cookie is replaced at every use and stored only as a hash. If an older one is presented again, which is the sign of a copied cookie, the session is ended.
- Signing out ends the session on the server, not just in the browser. An ended session stops being accepted within 30 seconds.
- A session that is not used expires: after 30 days by default, and never later than 60.
- An administrator who deactivates a user ends that person’s sessions. A password reset ends all of them.
- Sign-ins, sign-outs, and sessions ended by an administrator or by a password reset or change are in the audit trail.
Evidence and document files are stored privately
A photograph taken as evidence or a contract uploaded as a document has no public address.
- Files are kept in private storage, in a folder of their own for each workspace. Every download goes through the API, which checks that the person is signed in and may see the record the file belongs to.
- A file is always sent as a download, with headers that stop a browser from running it as a page.
- An upload is accepted only when its type is on the allowed list and its content matches the type it claims. Size limits apply to each file and to the storage of the plan.
- A SHA-256 checksum is recorded with every file.
- The evidence and the checklist of a completed task are locked, and every version of a document is kept.
What this page does not claim
A security page is only useful if it also says where it stops.
- No certification
- WorkVigil holds no security certification and this page claims none. If your company needs one, ask us where that stands before you rely on it.
- Hosting
- Where the servers are, how backups are taken and how disks and connections are encrypted depend on the hosting, and are not stated on this page.
- Virus scanning
- Uploaded files are not scanned for viruses. They are restricted by type and size, and only ever served as downloads.
- Company-managed single sign-on
- SAML single sign-on, enforced for a whole company, is not available.
How to reach us
Report a security concern
If you have found a weakness in WorkVigil, or need an answer this page does not give before you can decide, write to us. Say what you saw and how to reproduce it; please do not include other people’s data.
See it with your own work
Start a 14-day free trial of everything in Business. No card is needed.
How personal data is handled is set out in the privacy policy.
