Data Guard
Scenario
This example uses a real MonSQLize collection and composes caller Mongo filters, exact tenant isolation, role where conditions, field projection, insert/update ownership checks, and denied field/write probes.
Run
The canonical source is the docs:data-guard:start to docs:data-guard:end block in examples/data-guard.mjs.
First Check the Result
A successful run confirms matchedCount: 1, deniedFieldCode: 'FIELD_PERMISSION_DENIED', writeGuard.deniedWriteCode: 'PERMISSION_DENIED', and persistedRows: 5.
Source walkthrough
The protected route or companion source used by this scenario is:
The caller filter is combined with tenantId, the persisted merchantId = claims.merchantId condition, and field projection permissions before MongoDB is called.
1. Define row, field, and write policy
Purpose and target. This operation explains roles.create, roles.allow, roles.deny, userRoles.assign in the order the runnable source uses them. It identifies which object is being created, read, projected, or enforced and which output group records the evidence.
State, arguments, and result. The arguments come from trusted scope, role, subject, menu, API, or data state already shown in the source block. Each call either returns its own raw envelope or contributes a selected field to composition.
Failure and next step. If validation, revision, source integrity, authentication, or authorization fails, stop at that layer, refresh the trusted state, and rerun the matching operation. Do not widen permissions or bypass the guarded facade to make the example pass.
API reference. See roles for exact signatures, response wrappers, and public error codes.
2. Create the authorized collection
Purpose and target. This operation explains forSubject, data.collection in the order the runnable source uses them. It identifies which object is being created, read, projected, or enforced and which output group records the evidence.
State, arguments, and result. The arguments come from trusted scope, role, subject, menu, API, or data state already shown in the source block. Each call either returns its own raw envelope or contributes a selected field to matchedRows, matchedCount, deniedFieldCode, writeGuard, persistedRows.
Failure and next step. If validation, revision, source integrity, authentication, or authorization fails, stop at that layer, refresh the trusted state, and rerun the matching operation. Do not widen permissions or bypass the guarded facade to make the example pass.
API reference. See authorized-collection for exact signatures, response wrappers, and public error codes.
3. Read with composed constraints
Purpose and target. This operation explains find in the order the runnable source uses them. It identifies which object is being created, read, projected, or enforced and which output group records the evidence.
State, arguments, and result. The arguments come from trusted scope, role, subject, menu, API, or data state already shown in the source block. Each call either returns its own raw envelope or contributes a selected field to matchedRows, matchedCount, deniedFieldCode.
Failure and next step. If validation, revision, source integrity, authentication, or authorization fails, stop at that layer, refresh the trusted state, and rerun the matching operation. Do not widen permissions or bypass the guarded facade to make the example pass.
API reference. See authorized-collection for exact signatures, response wrappers, and public error codes.
4. Enforce ownership before and after writes
Purpose and target. This operation explains insertOne, updateOne in the order the runnable source uses them. It identifies which object is being created, read, projected, or enforced and which output group records the evidence.
State, arguments, and result. The arguments come from trusted scope, role, subject, menu, API, or data state already shown in the source block. Each call either returns its own raw envelope or contributes a selected field to writeGuard, persistedRows.
Failure and next step. If validation, revision, source integrity, authentication, or authorization fails, stop at that layer, refresh the trusted state, and rerun the matching operation. Do not widen permissions or bypass the guarded facade to make the example pass.
API reference. See authorized-collection for exact signatures, response wrappers, and public error codes.
Expected output
The following JSON is the Example summary output generated by printExample(). It combines selected fields from several API calls and is not the raw response of one method.
composition provenance. This output group is produced by the data-policy walkthrough and should be read together with roles.allow. It is a selected, documented example field rather than a new API response shape.
matchedRows provenance. This output group is produced by the data-read walkthrough and should be read together with find. It is a selected, documented example field rather than a new API response shape.
matchedCount provenance. This output group is produced by the data-read walkthrough and should be read together with find. It is a selected, documented example field rather than a new API response shape.
deniedFieldCode provenance. This output group is produced by the data-read walkthrough and should be read together with find. It is a selected, documented example field rather than a new API response shape.
writeGuard provenance. This output group is produced by the data-write walkthrough and should be read together with insertOne. It is a selected, documented example field rather than a new API response shape.
persistedRows provenance. This output group is produced by the data-write walkthrough and should be read together with insertOne. It is a selected, documented example field rather than a new API response shape.
Production boundary
Raw fixture writes happen only before the guard is used. Production reads and writes should go through AuthorizedCollection; shared business transactions should pass a host-owned transaction.
Related
See Data Permissions, Authorized Collection API, and Resources and Rules.