Hiding a button is not access control

Every restriction in VCMS is enforced by the API that serves the data. The console reflects those rules; it does not implement them, and it cannot be talked out of them by anybody with a browser console open.

VCMS · Reports / Audit logIllustrative
Audit logChain verified
09:58:04muster_activatedwarden.02
09:41:22contractor_document_reviewedsafety.01
09:12:07visit_checkinreception.03
08:44:51access_credential_issuedsecurity.01

Append-only and hash-chained. A verify run reports a failed check differently from a broken chain, because conflating them either raises a false alarm or hides a real one.

An illustration of the VCMS Reports / Audit log screen, reconstructed from the application's own markup and stylesheet. Every name, organisation, site and figure shown is invented for the purpose of this illustration.
Authorisation

Permissions, not role names

80 granular capabilities across 9 console roles. Routes gate on the permission, so an organisation can move a capability between roles without a code change and without a route quietly staying open.

Resolved per requestPermissions are read per request rather than carried in the access token, so an administrator’s change takes effect within a minute, not when a token that lasts half an hour happens to expire.
Editable per organisationThe default map is the fallback. A tenant that has customised its roles runs on its own rows.
Tier-guarded assignmentAn actor may assign only roles below their own tier. Equal tiers cannot assign each other, so a manager cannot mint another manager.
Site scopingA user restricted to Site A cannot read Site B, through the console or by calling the API directly. Out-of-scope records answer 404 rather than 403, so identifiers stay unenumerable.
Tenant isolationSeparate database schemas per organisation in production, so one tenant’s rows are not one missing WHERE clause away from another’s.
Delegated administrationTime-bounded grants that are issued, visible and revocable, rather than a second permanent administrator account nobody remembers creating.
Roles

Nine roles, each shaped by a job

These are the roles in the product. Every one of them is a permission set you can edit. The names are a starting point, not a constraint.

AdministratoradminThe whole platform, including who else may do what.
ManagermanagerDay-to-day operations across visitors, contractors and reporting.
Project administratorproject_adminA programme of contractor work: onboarding, shifts, work orders.
Safety officersafety_officerWHS: incidents, policies, inductions and compliance evidence.
AuditorauditorRead and verify. Reports, analytics and the audit chain, and nothing that writes.
SecuritysecurityThe gate: screening decisions, credentials and who is on site.
WardenwardenEmergency response: activate a muster, mark the roll, resolve it.
ReceptionreceptionThe front desk: check people in and out, notify hosts, print badges.
HosthostInvite the people you are expecting, and see your own visitors.

Contractors and visitors are not console roles. They reach the system through invitation links and a self-service portal with its own, much narrower, authorisation.

Authentication

Sign-in, and what happens on a new device

Multi-factor that does not punish somebody for using the same laptop every day, and does not wave through a session appearing from somewhere new.

Three ways in

Password, Google, or Microsoft. Single sign-on honours the same multi-factor requirements as a password login. An identity provider is not a way around your own policy.

Trusted for a day

A verified device on a known network is not challenged again for 24 hours. A different device, or the same device on a different network, is challenged again.

Revocation means revocation

Ending a session or resetting somebody’s MFA revokes every trusted device with it, so a lost laptop is one action rather than a hope.

Accountability

An audit log that can be checked, not just read

Append-only was a property of how the code happened to behave. It is now a rule that something enforces, which is a different claim.

Every consequential action is written to a hash-chained log. Each entry chains to the hash before it, and a verify endpoint answers whether the chain is intact. It reports a failed check differently from a broken chain, because conflating the two either raises a false alarm or hides a real one.

The subtle part is deletion. A chain where each row references the previous hash value survives having a row removed: the surviving links still line up. So append-only is enforced at two levels rather than assumed, and a missing afternoon is detectable.

The log exports to CSV, and read access to it is itself a permission. The auditor role holds it and holds almost nothing that writes.

  • Actor, entity, event type and payload on every entry.
  • A verify run you can trigger from the console.
  • Forwarding to an external log sink, with a cursor so nothing is sent twice.
  • Read access is a permission, and reads of sensitive records are themselves recorded.
Data handling

Where data goes, and how it stops going there

Sign-in and MFA

Password, Google or Microsoft, with multi-factor that remembers a device for a day.

  • A known device on a known network is not challenged again for 24 hours; a new device or a new network is.
  • Revoking a session or resetting MFA revokes every trusted device with it.

Notification control

59 branded message templates, with the channels for each under your control.

  • Email through your own SMTP relay or a delivery provider; SMS as an opt-in.
  • Every message is queued in an outbox with its delivery state, so "was this person actually emailed?" is a question with an answer.

Retention and disposal

Say how long you keep personal information, and have the platform actually do it.

  • Identity images live in a separate store, so disposal deletes rows rather than relying on somebody remembering to null a column.
  • Export or purge everything held about one subject.

Outbound integrations

Send events where your organisation already looks.

  • Signed webhooks and Microsoft Teams cards.
  • SharePoint lists, a SharePoint document mirror and Power BI push datasets, each of which names the exact setting it is missing rather than failing quietly.
On data residency, plainly.

VCMS carries a residency register: for a running deployment it computes which services are carrying data where, and can refuse egress to a destination outside the region you declare. That is a real, checkable mechanism. It is not the same as a finished guarantee. Where a deployment depends on a third party that cannot be pinned to your region, the register names it rather than glossing over it. We would rather show you that register than make a claim you cannot verify.

Bring your security questionnaire

We would rather answer it against the actual mechanisms than send back a document. Ask about the parts that are not finished, too.