Skip to main content

Overview

The schema configuration file (schema.yml) defines the structure of your collections including field types, validation constraints, indexes, access control fields, and versioning settings.

Configuration Structure

version: "1.0"
settings:
  # Global schema settings
collections:
  # Collection definitions

Global Settings

Define default behaviors applied across all collections.
settings.default_tenant_field
string
Default field name used for tenant isolation across all collections.Example: tenant_id
settings.default_owner_field
string
Default field name used for owner-based access control.Example: owner_id
settings.auto_timestamps
boolean
Automatically manage created_at and updated_at fields for all collections.
settings.id_type
string
default:"objectId"
Default ID type for documents. Options: objectId, uuid, string.

Example

settings:
  default_tenant_field: "tenant_id"
  default_owner_field: "owner_id"
  auto_timestamps: true
  id_type: objectId

Collection Definition

Define the structure for each collection.
collections:
  users:
    fields:
      # Field definitions
    indexes:
      # Index definitions
    access:
      # Access control fields
    versioning:
      # Version management
    hierarchy:
      # User hierarchy settings

Field Types

Permission Mongo supports the following field types:
fields.<name>.type
string
required
The data type of the field.Supported types:
  • string - Text data
  • number - Floating point numbers
  • integer - Whole numbers
  • boolean - True/false values
  • date - Date and time values
  • objectId - MongoDB ObjectID
  • uuid - UUID strings
  • array - Array of values (requires items config)
  • object - Nested object (requires properties config)
  • any - Any data type (no validation)

Field Options

Basic Constraints

fields.<name>.required
boolean
default:"false"
Whether the field is required on document creation.
fields.<name>.default
any
Default value when field is not provided. Supports static values and expressions.
fields.<name>.immutable
boolean
default:"false"
Field cannot be modified after document creation.
fields.<name>.auto
boolean
default:"false"
Automatically generate value on document creation (e.g., timestamps, IDs).
fields.<name>.auto_update
boolean
default:"false"
Automatically update value on document modification (e.g., updated_at).

String Constraints

fields.<name>.min_length
integer
Minimum string length.
fields.<name>.max_length
integer
Maximum string length.
fields.<name>.pattern
string
Regular expression pattern the string must match.
fields.<name>.format
string
Predefined format validation. Options: email, url, date, time, datetime.

Numeric Constraints

fields.<name>.min
number
Minimum numeric value.
fields.<name>.max
number
Maximum numeric value.

Enum Values

fields.<name>.enum
array
List of allowed values for the field.

References

fields.<name>.ref
string
Name of the collection this field references (foreign key).

Array Fields

Define array fields with item type validation:
tags:
  type: array
  items:
    type: string
    max_length: 50

addresses:
  type: array
  items:
    type: object
    properties:
      street:
        type: string
        required: true
      city:
        type: string
        required: true
      zip:
        type: string
        pattern: "^[0-9]{5}$"

Object Fields

Define nested object structures:
address:
  type: object
  properties:
    street:
      type: string
      required: true
    city:
      type: string
      required: true
    state:
      type: string
      max_length: 2
    zip:
      type: string
      pattern: "^[0-9]{5}$"

Computed Fields

Define fields calculated from other field values:
fields.<name>.computed.expr
object
required
MongoDB aggregation expression to compute the field value.
fields.<name>.computed.store
boolean
default:"false"
Whether to persist the computed value in the database.
fields.<name>.computed.recompute_on
array
List of fields that trigger recomputation when changed.

Example

full_name:
  type: string
  computed:
    expr:
      $concat: ["$first_name", " ", "$last_name"]
    store: true
    recompute_on: ["first_name", "last_name"]

Indexes

Define indexes for query optimization and uniqueness constraints.
indexes[].fields
array
required
List of field names included in the index.
indexes[].order
array
Sort order for each field: 1 for ascending, -1 for descending. Defaults to 1 for all fields.
indexes[].unique
boolean
default:"false"
Whether the index enforces uniqueness.
indexes[].sparse
boolean
default:"false"
Whether the index is sparse (only indexes documents containing the indexed fields).
indexes[].name
string
Custom name for the index.

Examples

indexes:
  # Unique email index
  - fields: ["email"]
    unique: true
  
  # Compound index for queries
  - fields: ["tenant_id", "status"]
    order: [1, 1]
  
  # Descending index for sorting
  - fields: ["created_at"]
    order: [-1]
    name: "idx_created_desc"

Access Control

Define fields used for tenant isolation and ownership.
access.tenant_field
string
Field name used for multi-tenant isolation. Overrides global default_tenant_field.
access.owner_field
string
Field name used for owner-based access control. Overrides global default_owner_field.

Example

access:
  tenant_field: "company_id"
  owner_field: "created_by"

Versioning

Configure document versioning at the collection level.
versioning.enabled
boolean
default:"false"
Enable version tracking for documents in this collection.
versioning.mode
string
default:"full"
Version storage mode:
  • full - Store complete document snapshots
  • diff - Store only changed fields
versioning.max_versions
integer
Maximum number of versions to retain per document.
versioning.retention_days
integer
Number of days to retain old versions.

Example

versioning:
  enabled: true
  mode: "diff"
  max_versions: 50
  retention_days: 90

Hierarchy Configuration

Configure user hierarchy for permission inheritance.
hierarchy.user_id_field
string
Field containing the user ID for hierarchy lookups.
hierarchy.manager_field
string
Field containing the manager’s user ID.

Example

hierarchy:
  user_id_field: "_id"
  manager_field: "manager_id"

Complete Example

version: "1.0"

settings:
  default_tenant_field: "tenant_id"
  default_owner_field: "owner_id"
  auto_timestamps: true
  id_type: objectId

collections:
  users:
    fields:
      _id:
        type: objectId
        auto: true
      email:
        type: string
        required: true
        format: email
      name:
        type: string
        required: true
        min_length: 1
        max_length: 255
      role:
        type: string
        required: true
        enum: ["admin", "manager", "user", "viewer"]
      tenant_id:
        type: objectId
        required: true
      owner_id:
        type: objectId
      manager_id:
        type: objectId
        ref: users
      created_at:
        type: date
        auto: true
        immutable: true
      updated_at:
        type: date
        auto_update: true
    indexes:
      - fields: ["email"]
        unique: true
      - fields: ["tenant_id", "role"]
    access:
      tenant_field: "tenant_id"
      owner_field: "owner_id"
    versioning:
      enabled: true
      mode: "diff"
      max_versions: 50
      retention_days: 90
    hierarchy:
      user_id_field: "_id"
      manager_field: "manager_id"

  documents:
    fields:
      _id:
        type: objectId
        required: true
      title:
        type: string
        required: true
        max_length: 500
      content:
        type: string
      status:
        type: string
        enum: ["draft", "published", "archived"]
        default: "draft"
      tenant_id:
        type: objectId
        required: true
      owner_id:
        type: objectId
        required: true
      tags:
        type: array
        items:
          type: string
      metadata:
        type: object
        properties:
          views:
            type: integer
            default: 0
          last_viewed:
            type: date
      created_at:
        type: date
        auto: true
        immutable: true
      updated_at:
        type: date
        auto_update: true
    indexes:
      - fields: ["tenant_id", "status"]
      - fields: ["owner_id"]
      - fields: ["tags"]
    access:
      tenant_field: "tenant_id"
      owner_field: "owner_id"
    versioning:
      enabled: true
      mode: "full"
      max_versions: 100
      retention_days: 365

Environment Variables

Schema configuration supports environment variable substitution:
collections:
  users:
    fields:
      default_role:
        type: string
        default: "${ENV.DEFAULT_USER_ROLE}"

Loading Schema Configuration

Load the schema configuration at server startup:
permission-mongo --schema=/path/to/schema.yml
Or use the PM_SCHEMA environment variable:
export PM_SCHEMA=/path/to/schema.yml
permission-mongo

Build docs developers (and LLMs) love