Files
kontextual-engine/docs/cmis-profiled-access-points-implementation.md

169 lines
6.6 KiB
Markdown

# CMIS Profiled Access Points Implementation
Date: 2026-05-06
Status: Browser Binding subset implemented and capability-hardened.
## Implemented Slice
`src/kontextual_engine/core/cmis.py` defines the CMIS profile and access-point
boundary used by the future API adapter:
- `CMISBinding`
- `CMISCapability`
- `CMISAction`
- `CMISAccessProfile`
- `CMISAccessPoint`
- `CMISDomainMapper`
- `CMISObjectProjection`
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.
Repository info now uses conservative standard CMIS flags: optional services we
do not implement are advertised as `false` or `none`, while Kontextual-specific
projection behavior is exposed through repository feature metadata and an
unsupported-feature catalog.
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 /cmis`
- `GET /cmis/{access_point_id}/browser`
- `GET /cmis/{access_point_id}/browser/types`
- `GET /cmis/{access_point_id}/browser/children`
- `GET /cmis/{access_point_id}/browser/object/{object_id}`
- `GET /cmis/{access_point_id}/browser/content/{object_id}`
- `GET /cmis/{access_point_id}/browser/query`
- `GET /cmis/{access_point_id}/browser/relationships`
- `GET /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/document`
- `POST /cmis/{access_point_id}/browser/object/{object_id}/properties`
- `POST /cmis/{access_point_id}/browser/object/{object_id}/content`
- `POST /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.
The authoring slice intentionally supports only `kontextual:metadata:<key>`
property updates. Attempts to update standard `cmis:*` properties return
structured validation diagnostics instead of being silently ignored.
## ACL And Redaction Slice
The Browser Binding adapter now projects profile-derived ACLs through
`GET /cmis/{access_point_id}/browser/acl/{object_id}`. ACL entries are derived
from the access profile and actor context:
- visible objects grant the current actor `cmis:read`,
- authoring profiles also project `cmis:write` and `cmis:delete`,
- public objects include a read-only `anyone` ACE,
- hidden objects return `not found` rather than partial metadata.
Relationship listings and change logs now apply the same asset visibility gates
as object reads. This prevents indirect leakage of confidential or restricted
asset IDs through relationship targets or audit-backed change entries.
## Projection-Only Multifiling
CMIS navigation now supports projection-only parent maps. The same asset can be
listed under several derived folder paths, including source system, topics,
owner, lifecycle, and asset type. These folders are navigation projections; they
do not duplicate assets and do not become canonical storage locations.
`GET /cmis/{access_point_id}/browser/parents/{object_id}` returns the projected
parent folders for one asset. `GET /cmis/{access_point_id}/browser/children`
supports folder-scoped navigation through those projected paths.
The standard CMIS `capabilityMultifiling` flag remains `false` because the
engine does not expose mutating filing services such as `addObjectToFolder` or
`removeObjectFromFolder`.
## Fixture And Optional TCK Integration
CMIS fixtures now act as active compatibility contracts:
- `examples/cmis/capability-fixtures.json` defines profile expectations and
capability groups,
- `tests/cmis/test_cmis_fixture_integration.py` compares those expectations to
implemented profiles and access-point shapes,
- `tests/cmis/opencmis-tck/tck-subset-map.json` maps fixture capability groups
to selected OpenCMIS TCK groups,
- `tests/cmis/opencmis-tck/tck-result-template.json` captures optional TCK
result summaries and known capability gaps.
The default Python suite validates the fixture/TCK mapping without requiring
Java or Maven. Actual OpenCMIS TCK execution remains opt-in.
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.
Deployment and compatibility posture are documented in
`docs/cmis-deployment-compatibility.md`.