Every HTTP request to the MDCMS server passes through a layered middleware chain before reaching a route handler. This page documents the full request flow, authentication mechanisms, RBAC model, API key scopes, and response envelope format.Documentation Index
Fetch the complete documentation index at: https://docs.mdcms.ai/llms.txt
Use this file to discover all available pages before exploring further.
Middleware Chain
The server processes each request through the following stages, in order.| Stage | Responsibility |
|---|---|
| 1. CORS | Validates the Origin header against MDCMS_STUDIO_ALLOWED_ORIGINS. Handles OPTIONS preflight requests for Studio browser routes. Rejects disallowed origins with 403 FORBIDDEN_ORIGIN. |
| 2. Request Logging | Captures request metadata (method, URL, timing) for observability. |
| 3. CSRF | For cookie-authenticated mutations, verifies the X-MDCMS-CSRF-Token header matches the mdcms_csrf cookie. API key requests bypass CSRF since they use Authorization headers. |
| 4. Authentication | Identifies the calling principal — either an API key (via Authorization: Bearer mdcms_key_...) or a session (via cookie). |
| 5. Target Routing | Validates that scoped routes include the required X-MDCMS-Project and/or X-MDCMS-Environment headers. Returns 400 if headers are missing. |
| 6. Authorization | Checks the authenticated principal’s permissions against the requirements of the target route (scope, role, resource path). |
| 7. Route Handler | Executes the business logic (content CRUD, schema sync, media upload, etc.). |
| 8. Response Envelope | Wraps the result in a standard JSON response format with appropriate status codes and CORS headers. |
Authentication Flows
MDCMS supports three authentication mechanisms, each designed for a different client context.API Key Authentication
API keys are intended for server-to-server communication, CI/CD pipelines, and SDK usage.- Keys use a
mdcms_key_prefix for easy identification in logs. - The key value is hashed (SHA-256) before storage — the raw key is only shown once at creation time.
- Each key carries an array of operation scopes (e.g.,
content:read,schema:write) and a context allowlist restricting which project/environment pairs it can access. - Keys support optional expiration via
expiresAtand soft revocation viarevokedAt.
Session Authentication
Sessions are used by the Studio UI and browser-based interactions.- Created via better-auth after successful password, OIDC, or SAML authentication.
- Stored in the
sessionstable with a session token cookie. - Inactivity timeout: 2 hours of no activity expires the session.
- Absolute max age: 12 hours regardless of activity.
- CSRF protection: Mutations require a
X-MDCMS-CSRF-Tokenheader matching themdcms_csrfcookie (24-byte random token). - Supported identity providers: password (credential), OIDC (Okta, Azure AD, Google Workspace, Auth0), SAML.
CLI Device Flow
The CLI authenticates via a device-authorization-like flow:Challenge creation
The CLI creates a login challenge with a 10-minute TTL, specifying the
target project, environment, redirect URI, and requested scopes.
Browser authorization
The user opens a browser URL, authenticates via session
(password/OIDC/SAML), and authorizes the CLI challenge. The challenge status
transitions from
pending to authorized.content:read, content:read:draft, content:write, content:delete, schema:read, schema:write.
RBAC Model
MDCMS implements role-based access control with hierarchical scoping.Roles
Roles form an ordered hierarchy. Higher roles inherit all capabilities of lower roles.| Role | Level | Scope Restriction |
|---|---|---|
viewer | 0 | Global, project, or folder prefix |
editor | 1 | Global, project, or folder prefix |
admin | 2 | Global only |
owner | 3 | Global only |
admin and owner roles are restricted to global scope by a database check
constraint. They cannot be scoped to a specific project or folder prefix.Scopes
Each RBAC grant is bound to a scope that determines where the role applies:| Scope Kind | Fields Required | Meaning |
|---|---|---|
global | None | Applies to all projects and environments. |
project | project | Applies to all environments within a specific project. |
folder_prefix | project, environment, pathPrefix | Applies only to documents whose path starts with the given prefix within a specific project and environment. |
Role Capability Matrix
| Capability | viewer | editor | admin | owner |
|---|---|---|---|---|
content:read | Yes | Yes | Yes | Yes |
content:read:draft | — | Yes | Yes | Yes |
content:write | — | Yes | Yes | Yes |
content:publish | — | Yes | Yes | Yes |
content:unpublish | — | Yes | Yes | Yes |
content:delete | — | Yes | Yes | Yes |
schema:read | Yes | Yes | Yes | Yes |
schema:write | — | — | Yes | Yes |
projects:read | Yes | Yes | Yes | Yes |
projects:write | — | — | Yes | Yes |
user:manage | — | — | Yes | Yes |
settings:manage | — | — | Yes | Yes |
API Key Scopes
API keys use a fine-grained scope model independent of RBAC roles. Each key declares which operations it is permitted to perform.| Scope | Description |
|---|---|
content:read | Read published content documents. |
content:read:draft | Read draft (unpublished) content documents. |
content:write | Create and update content documents. |
content:write:draft | Legacy scope for draft writes (aliases content:write). |
content:publish | Publish documents (create immutable version snapshots). |
content:delete | Soft-delete and restore content documents. |
schema:read | Read schema registry entries and sync state. |
schema:write | Sync schema changes to the server. |
media:upload | Upload media files to S3 storage. |
media:delete | Delete media files. |
webhooks:read | List and inspect webhook configurations. |
webhooks:write | Create, update, and delete webhook configurations. |
environments:clone | Clone content between environments. |
environments:promote | Promote content from one environment to another. |
migrations:run | Execute content migrations. |
projects:read | Read project metadata. |
projects:write | Update project settings. |
Response Envelopes
All API responses use one of three standard envelope formats.Single Resource
Paginated Collection
Error
code, a human-readable message, and an ISO-8601 timestamp. The optional details object provides context-specific debugging information. The requestId is echoed from the X-Request-Id header when present.
CORS Configuration
Studio browser routes (content, schema, media, auth, search, webhooks, actions, environments, collaboration, and Studio bootstrap) are protected by origin validation. Configure allowed origins via theMDCMS_STUDIO_ALLOWED_ORIGINS environment variable:
Origin header matches either the request’s own origin (same-origin) or one of the configured allowed origins. Requests from disallowed origins receive a 403 FORBIDDEN_ORIGIN response. Preflight OPTIONS requests are handled automatically with the appropriate access-control-allow-* headers.