s-m-r-t
Open the s-m-r-t source on GitHub Switch to dark color scheme
← Reference

Reference

Generated interfaces fail closed

Generated routes require an authenticated principal unless public access is explicitly declared, and field policy is applied before data leaves or enters the application.

Authentication is the default

When api.public is not set, generated reads and writes require a resolved principal. Use public: "read" to open only reads or public: true when every generated action is intentionally public.

Invoice.ts
typescript
@smrt({
  api: { include: ['list', 'get', 'create', 'update'] }
})
class Invoice extends SmrtObject {
  amount = 0;
}

// No api.public declaration: generated routes require authentication.

Sensitive fields close both read paths

A sensitive field is removed from public serialization and rejected in collection filters. Both protections matter: hiding output alone would still allow a caller to probe a secret value through repeated where clauses.

Write policy blocks mass assignment

Generated create and update handlers filter the request body before the model receives it. They remove read-only fields, IDs, timestamps, tenant IDs, underscore-prefixed keys, and fields outside an optional writable allowlist.

Application code still owns its boundary

Generated routes enforce these defaults. Custom actions, jobs, direct collection calls, external callbacks, and product-specific threat models still need deliberate principal, tenant, permission, and input checks.

Authentication is not authorization

These defaults answer whether a caller is known. Authorization is a separate decision about the operation and tenant. An application guard checks the permission catalog. On Postgres, generated row-level security policies can also check it.

Field policy is presentation, not enforcement

A field hidden by field policy is still writable through the generated API unless the model says otherwise. A policy cannot store a default on a sensitive, transient, or read-permission-gated field, and the batch resolve response omits those fields for every caller.