3.9 KiB
CMIS Profiled Access Points Implementation
Date: 2026-05-06
Status: profile and mapper slices implemented.
Implemented Slice
src/kontextual_engine/core/cmis.py defines the CMIS profile and access-point
boundary used by the future API adapter:
CMISBindingCMISCapabilityCMISActionCMISAccessProfileCMISAccessPointCMISDomainMapperCMISObjectProjection
The layer is intentionally small. It decides whether a CMIS action is allowed for a profile and whether an engine asset may be exposed through an access point. It does not implement CMIS routes and does not duplicate asset storage, metadata, relationship, policy, or audit services.
Built-In Profiles
readonly-browser: Browser Binding read profile over public/internal assets.governed-authoring: Browser Binding profile with selected create/update and content stream mutations.admin-export: service-account-only export profile with broad visibility.compat-tck: Browser Binding profile intended for selected OpenCMIS TCK compatibility tests.
Enforcement Boundary
Profiles can restrict exposure by:
- CMIS capability,
- mutation allowance,
- actor type,
- sensitivity,
- asset type,
- topic,
- source system,
- metadata deny rules.
Decisions return existing PolicyDecision objects so later CMIS routes can
emit compatible diagnostics and audit records without inventing another policy
model.
Mapper Slice
CMISDomainMapper projects existing engine state into CMIS-shaped envelopes:
- repository info and CMIS 1.1 Browser Binding capability flags,
- base type definitions for document, folder, relationship, policy, item, and secondary,
- engine assets as CMIS document projections,
- representation metadata as content stream descriptors,
- asset versions as CMIS version properties,
- relationship primitives as CMIS relationship objects,
- profile-derived allowable actions.
The mapper returns None for assets or relationships that the access-point
profile must not expose. It does not fetch from repositories directly; callers
provide the asset, representations, versions, metadata records, and
relationships they have already authorized or loaded.
Browser Binding MVP Slice
The service exposes profile-scoped Browser Binding MVP routes:
GET /cmisGET /cmis/{access_point_id}/browserGET /cmis/{access_point_id}/browser/typesGET /cmis/{access_point_id}/browser/childrenGET /cmis/{access_point_id}/browser/object/{object_id}GET /cmis/{access_point_id}/browser/content/{object_id}GET /cmis/{access_point_id}/browser/queryGET /cmis/{access_point_id}/browser/relationshipsGET /cmis/{access_point_id}/browser/changes
The MVP supports repository info, type definitions, synthetic root children, object reads, content stream descriptors, a constrained document query subset, relationship objects, and audit-backed change entries. Unsupported query grammar returns structured diagnostics.
Governed Authoring Slice
The Browser Binding adapter now exposes selected mutation routes for profiles that allow authoring:
POST /cmis/{access_point_id}/browser/documentPOST /cmis/{access_point_id}/browser/object/{object_id}/propertiesPOST /cmis/{access_point_id}/browser/object/{object_id}/contentPOST /cmis/{access_point_id}/browser/object/{object_id}/delete
These routes delegate to existing engine services:
- document creation uses
AssetRegistryService.create_asset, - property updates add governed metadata records,
- content stream updates add asset representations and content-change versions,
- delete requests transition the asset lifecycle to
delete_requested.
Read-only profiles reject the same mutations with CMIS-shaped authorization diagnostics before touching engine services.
Route-level tests are present but skip when the optional FastAPI/httpx service dependencies are not installed. Runtime-level Browser Binding tests cover the same behavior in the default Python test suite.