Websites had their WordPress moment. SaaS is having its BuildWithHQ moment. See the new BuildWithHQ homepage →
Home/Platform/Security and audit
Security and audit

Enforcement is normal. Being able to prove it is not.

Most platforms can tell you who edited a record. Far fewer can tell you who read it, what the AI retrieved, or whether that person was genuinely permitted to at the time. BuildWithHQ records all of it, and can re-derive the decision afterwards to check that the log is telling the truth.

One model

Resolved once, used by every read path

The set of records a user is allowed to see is computed in a single place, and every feature that reads tenant data draws from that set. It is a filter, not a gate: a record you have no role on is absent from the result rather than refused. This is why the tenth module doesn't leak — there is no second code path to forget, and no rejection branch to get wrong.

Record-level roles

Permissions attach to individual records, not just to screens. A user can hold several roles at once, and one record can be shared with several roles without duplicating it. Called DataRoles in the product.

Branch and region boundaries

A second boundary alongside roles, for branches, regions, facilities, and territories. The role must allow it and the location must match. Called location scope in the product.

Separate permission flags

Reading a record, exporting it, and letting the AI read it are three different permissions, not one.

Field-level encryption

Encrypted fields drop out of search and AI retrieval automatically, and every reveal is authorized and logged.

A filter, not a gate

Pages load with what the person can see. An unentitled record is absent from the result set rather than refused, so nothing confirms that it exists.

What gets recorded

Routine reads, and the privileged operations that can be refused

Read the trust documentation

Encrypted-field reveals

Revealing an encrypted field is an explicit operation, separate from rendering a page. It is authorized on its own, it can be refused, and refusals are recorded with the same weight as successful reveals.

AI retrievals

Every AI query records the envelope it drew from, so 'what did the assistant see' has an answer. The envelope is resolved before retrieval, so the model is never handed anything to filter out.

Exports

Who exported what, and when. Export is a distinct permission precisely so that it can be governed and reviewed separately from reading.

Authorization decisions

Not just the outcome but the inputs, so the decision can be reconstructed later rather than merely trusted.

Replay

Rewind a decision and check the log against reality

This is the capability that turns a log into evidence.

Roles change. People move between locations. Records are reassigned. That means a log entry from March cannot be judged against today's permission table — the honest question is whether the access was permitted at the time.

Two replay modes

  • As of then — re-derive the access envelope exactly as it stood when the query ran. This catches tampering, enforcement bugs, and forged log rows.
  • As of now — re-derive it under today's rules. This catches authorization drift: access that was legitimate then and would not be permitted today.

What a replay returns

A verdict, not a reassurance. The result is one of: verified, envelope mismatch, unauthorized retrieval, no longer authorized, or chain broken. Each is a specific finding you can act on, and each replay run is itself recorded.

An audit trail that only records successes is not an audit trail. Refused reveals and failed verifications are the entries that matter most in a review.

Why there is no stream of access-denied events

Record access resolves as a filter. A user never requests a record they have no role on and gets turned away, because the list, search, or panel they were looking at was built from their entitled set and never offered it. There is no rejection to log because there was no attempt to make.

That is deliberately stronger than refusing. An error response confirms a record exists and usually reveals something about it. Filtering at the source makes an unentitled record and a non-existent record indistinguishable from outside. Refusal is reserved for the operations that genuinely warrant it — revealing an encrypted field, exporting, and privileged actions — where the request is explicit and the refusal is meaningful.

Common questions

Questions about this

Do you log reads or only changes?

Both, and reads are the part most platforms skip. Encrypted-field reveals, AI retrievals, and exports are recorded as discrete events, including reveals that were refused. Ordinary reads of records a user is already entitled to are routine rather than exceptional.

What is replayable authorization?

The platform can re-derive a past access decision using the roles, locations, and record state as they existed at that moment, then compare the result against what was logged. The outcome is an explicit verdict rather than an assurance.

Can an administrator quietly delete a log entry?

The log rows are chained: each entry folds in the hash of the entry before it. Removing or altering a row breaks the chain, and a broken chain is itself a recorded verdict.

Is the platform SOC 2 certified?

Not yet. The security architecture, encryption approach, audit model, and data lifecycle are all documented publicly so you can evaluate them directly rather than relying on a badge.

Get started

Build it, then prove what it did

Create an account, explore the full builder console, and launch your first application on a custom domain. Nothing is charged while your application is still in development.

Start building today

No credit card required. The console preview, the documentation, and the architecture reference are all readable before you sign up.

Get started free Read the docs