Policy
Ramose policy has two public decisions: what facts a principal may read, and which exact operations the principal may invoke. Both belong to a named schema and run server-side.
New here? Start with Permissions.
Apply policy
Section titled “Apply policy”const ProjectSchema = Ramose.Schema("project-v1", { account: Account, task: Task,})
ProjectSchema.applyPolicy( { principal: Account.sub, roles: ["member", "admin"], }, ({ policy, actor, session }) => { policy.task.read.where(session.hasRole("member")) policy.task.read.where((task) => task.owner.eq(actor)) policy.task.fields.privateNote.read.where(session.hasRole("admin"))
policy.task.operations.setDone.where(session.hasRole("member")) policy.task.operations.delete.where(session.hasRole("admin")) },)Read authorization produces an immutable filtered database capability. All queries, relationship traversal, rule evaluation, counts, entity lookup, and target resolution run against it. The runtime does not query everything and filter the final rows.
Entity-level rules govern facts for a type. Field rules may narrow especially sensitive attributes. A field rule cannot widen an entity rule.
Multiple where calls for one target combine with OR. denyWhere overrides allows for the same target. Use always or never for an unconditional decision.
Operation policy
Section titled “Operation policy”policy.task.operations.createTask.where(session.hasRole("member"))policy.task.operations.setDone.where(session.hasRole("member"))policy.task.operations.delete.where(session.hasRole("admin"))Operation rules use names checked from the schema. They can depend on the session, but they cannot read the target resource. A targeted call also requires a visible target compatible with the owner. A targetless call requires the exact operation rule only.
Principal
Section titled “Principal”The principal is derived from a verified token and matched through the configured schema field. Token claims may supply stable identity and trusted coarse attributes; mutable membership and ownership normally belong in database rows so policy changes synchronize like other facts.
Database context
Section titled “Database context”Policy is evaluated for the authorized database before reads or operations run.
Composition
Section titled “Composition”Build small named rule fragments for roles, membership, ownership, and relationships. Use allOf for conjunction. Use multiple where calls for alternatives.
Relation traversal must be bounded and must not use fields that the rule itself masks. Schema policy validation rejects unknown definitions and incompatible targets before deployment.
Failure behavior
Section titled “Failure behavior”Policy configuration fails closed. A missing or invalid policy does not fall back to public access. Hidden, missing, wrong-type, and unauthorized targets collapse to public inaccessible or operation rejection behavior where a distinction would disclose facts.
Client-side role checks are presentation hints only. They may hide unavailable controls but never replace server enforcement.