Files
markitect-tool/docs/enterprise-access-control-integration.md

14 KiB

Enterprise Access-Control Integration

Date: 2026-05-04

Purpose

This note explains how Markitect's access-control gateway should integrate with enterprise IAM while respecting the local NetKingdom/key-cape direction.

The answer is yes: trust zones and access groups can map to canonical directory group membership, but Markitect should not trust raw AD group names directly. The enterprise shape should be:

OIDC/SAML/SCIM identity and directory plane
  -> canonical subject claims
  -> policy map and/or policy decision point
  -> Markitect policy gateway
  -> filtered document/query/context results

Markitect is the policy enforcement point for Markdown knowledge results. It should validate and normalize identity data through adapters, then call a policy decision point through the existing policy interfaces.

Canonical Enterprise Shape

The canonical enterprise pattern is the PEP/PDP/PIP/PAP split:

Component Markitect fit
PEP: policy enforcement point AccessPolicyGateway at query, search, context, workflow, export, and assisted-prompt boundaries.
PDP: policy decision point Local label policy for development; OpenFGA/SpiceDB, OPA/Rego, Cedar, or enterprise authorization service through adapters.
PIP: policy information point NetKingdom/key-cape OIDC claims, directory group resolution, object labels, backend metadata, workflow context, and environment attributes.
PAP: policy administration point Enterprise IAM/policy administration, plus versioned Markitect mapping files for labels, actions, trust zones, and emergency rules.

This keeps Markitect small and auditable. It enforces decisions where Markdown knowledge leaves a boundary, but it does not become the enterprise directory, SSO provider, or policy administration system.

Local Infrastructure Fit

The local canon already points the right way:

  • NetKingdom SSO is the reference identity provider.
  • Keycloak is the reference OIDC provider, with privacyIDEA-backed MFA.
  • key-cape is the lightweight OIDC/profile-enforcement path for local, sandbox, and bootstrap scenarios.
  • Services should trust OIDC tokens, validate issuer/audience/signature/expiry, and authorize from explicit roles/scopes.

Markitect should therefore consume the NetKingdom IAM profile rather than create its own identity standard.

Enterprise Reference Architecture

flowchart LR
    AD["AD / LDAP / HRIS"] --> SCIM["SCIM / Directory Sync<br/>(PIP)"]
    SCIM --> IdP["NetKingdom SSO<br/>Keycloak / key-cape-compatible OIDC"]
    IdP --> Token["OIDC Access Token<br/>roles, scopes, groups, org, assurance"]
    Token --> Mapper["Identity Claim Mapper"]
    Mapper --> Subject["PolicySubject"]
    Source["Markdown objects<br/>labels, paths, trust zones"] --> Object["PolicyObject"]
    Subject --> Gateway["Markitect AccessPolicyGateway<br/>(PEP)"]
    Object --> Gateway
    Gateway --> PDP["Policy Decision Point<br/>local / OpenFGA / OPA / Cedar"]
    PDP --> Decision["PolicyDecision + audit metadata"]
    Decision --> Boundary["Filtered query/search/context results"]

Identity Plane

OIDC should be the default authentication path for users and services. SAML may remain relevant for enterprise federation, but Markitect should normalize both into the same subject shape.

The canonical accepted claims should follow the NetKingdom IAM profile:

  • iss
  • sub
  • aud
  • exp
  • iat
  • scope or scp
  • preferred_username
  • roles or realm_access.roles
  • recommended groups, azp, email, name

For humans, Authorization Code + PKCE is the right login flow. For services, client credentials or workload identity should produce short-lived service tokens. OAuth token exchange can support hub-to-hub delegation where a service acts on behalf of a user.

Directory And Group Plane

Enterprise directories remain authoritative for group membership. Provisioning should use a standard such as SCIM where possible; AD/LDAP synchronization into Keycloak is also reasonable when NetKingdom owns the identity plane.

Important design rule:

directory groups -> canonical roles/scopes/trust labels -> Markitect subject

Avoid:

raw AD group name -> direct Markitect privilege

Reasons:

  • AD group names change and often encode organizational accidents.
  • Token group claims can be too large for large organizations.
  • Privilege should be expressed as app roles/scopes or an explicit mapping file.
  • Group membership freshness must be visible in the decision trail.

For Microsoft Entra-style group claims, large tenants may hit token group overage. Markitect should therefore support a group-resolution adapter rather than assuming all groups are always present in the token.

Policy Plane

The existing Markitect interfaces already provide the main policy boundary:

AccessPolicyGateway.authorize(subject, action, object_id, context)
AccessPolicyGateway.filter_results(subject, action, results, context)
AccessPolicyGateway.explain_decision(decision_id)

The existing data models also fit enterprise needs:

  • PolicySubject: identity, roles, groups/labels, allowed actions, attributes.
  • PolicyObject: path, labels, trust zone, attributes.
  • PolicyDecision: stable decision id, effect, reason, labels, trust zone, metadata.
  • PolicyFilterResult: filtered results, decisions, diagnostics, summary.

The adapter seams are also correct:

  • RelationshipPolicyAdapter for OpenFGA/SpiceDB/Zanzibar-style checks.
  • RulePolicyAdapter for OPA/Rego, Cedar, or other ABAC engines.

This follow-up adds the missing interface layer:

OIDC token or SAML assertion -> verified EnterpriseIdentity -> PolicySubject

Concrete adapters must validate issuer, audience, expiry, signature, and assurance metadata before any authorization decision is made. The core package now exposes protocol/data boundaries for this without taking a dependency on Keycloak, Entra, LDAP, SCIM, OpenFGA, OPA, or Cedar client libraries.

The current Markitect-side implementation provides deterministic local building blocks:

  • NetKingdomIdentityClaimsAdapter validates required IAM-profile claims, issuer, audience, token timestamps, roles/scopes, and production rejection of local development issuers for already trusted claims or explicit JWT fixtures.
  • EnterprisePolicyMap and LocalEnterprisePolicyMapper map groups, roles, and scopes into PolicySubject labels, trust zones, actions, and diagnostic attributes.
  • StaticDirectoryGroupResolver models group freshness and overage without a live directory dependency.
  • FlexAuthResourceManifest describes Markitect knowledge resources for future flex-auth registration.
  • LocalDecisionLogStore provides a JSONL development/test sink for decision records.

Live OIDC discovery, JWKS signature verification, directory synchronization, central policy administration, and durable enterprise audit should be provided by flex-auth/key-cape-facing adapters rather than Markitect core.

Canonical Subject Mapping

Recommended normalized shape:

subject:
  id: "oidc:<issuer>#<sub>"
  display_name: "Ada Lovelace"
  principal_type: human | service
  issuer: "https://sso.example.org/realms/netkingdom"
  audience: ["markitect-tool"]
  authorized_party: "markitect-cli"
  roles: [viewer, operator]
  scopes: [openid, profile, hub:read]
  groups:
    - /markitect/readers
    - /platform/architecture
  allowed_labels: [public, internal]
  trust_zones: [public, internal]
  assurance:
    mfa: true
    acr: "..."
    amr: ["pwd", "otp"]
  directory:
    source: keycloak | entra | ldap | scim
    refreshed_at: "2026-05-04T10:00:00Z"

The mapping file should translate enterprise groups and app roles to Markitect labels and actions:

id: markitect-enterprise-policy-map
issuer: https://sso.example.org/realms/netkingdom
audiences: [markitect-tool]
groups:
  /markitect/readers:
    allowed_labels: [public, internal]
    actions: [query, search, read]
  /markitect/stewards:
    allowed_labels: [public, internal, restricted]
    actions: [query, search, read, package, export]
roles:
  admin:
    allowed_labels: [public, internal, restricted]
    actions: [query, search, read, package, export, policy-admin]
scopes:
  markitect:read:
    actions: [query, search, read]
trust_zones:
  internal:
    required_groups: [/markitect/readers]

Command-line subject mapping:

mkt policy subject examples/policy/netkingdom-claims.yaml \
  --policy-map examples/policy/enterprise-policy-map.yaml

Data/Object Mapping

Markdown remains the source-friendly object labeling layer:

---
policy:
  labels: [internal]
  trust_zone: internal
  owner: team:platform-architecture
---

A Markitect knowledge base can publish an explicit flex-auth resource manifest:

id: markitect-example-knowledge-base
system: markitect-tool
actions: [read, query, search, package, export]
resources:
  - id: knowledge-base:markitect-example
    type: knowledge_base
  - id: document:internal-note
    type: document
    parent: knowledge-base:markitect-example
    path: examples/policy/private/internal-note.md
    labels: [internal]
    trust_zone: internal

For enterprise environments, object metadata should eventually include:

  • content labels/classification
  • repository/path
  • owning team or project
  • business domain
  • tenancy/org
  • retention or export constraints
  • provenance of label assignment

Path rules remain useful as a safety net, but document labels and backend metadata should become authoritative for cached/context-package retrieval.

Enforcement Points

Markitect should enforce policy at every point where knowledge leaves a boundary:

  • mkt cache query
  • mkt search
  • context package creation and activation
  • workflow outputs
  • assisted/LLM prompt assembly
  • export/render steps
  • backend APIs or future MCP resources

The highest-risk point is context assembly for agents. Before WP-0008 turns context caches into agent memory, policy must be able to answer:

  • who is activating the context package?
  • which token or service account is acting?
  • which labels/trust zones are included?
  • was anything denied or redacted?
  • can this package be reactivated later under the same policy assumptions?

Interface Confirmation

The WP-0009 infrastructure is a good foundation. It already has:

  • policy gateway protocol
  • local label gateway
  • explainable decisions
  • filter-before-return behavior
  • query/search integration
  • relationship and rule adapter boundaries

This follow-up adds these provider-neutral interfaces in markitect_tool.policy.adapters:

  1. IdentityClaimsAdapter

    • validates OIDC/JWT/SAML assertions
    • normalizes NetKingdom/key-cape-compatible claims into EnterpriseIdentity
  2. DirectoryGroupResolver

    • resolves group overage or stale claims
    • supports SCIM/Graph/LDAP/Keycloak admin APIs behind adapters
    • records freshness and source provenance
  3. EnterprisePolicyMapper

    • maps canonical groups, roles, scopes, and tenants to Markitect labels, trust zones, actions, and object constraints
  4. DecisionLogStore

    • persists policy decisions for query/context/workflow runs
    • records token hash, subject id, action, object id, policy version, result, reason, and redaction status
  5. workflow/runtime policy injection

    • subject_from_token
    • policy_map
    • required_assurance
    • emergency_justification

Concrete implementations remain future work. This is deliberate: key-cape and NetKingdom should own identity issuance and profile compliance, while Markitect owns normalization, policy envelopes, diagnostics, and enforcement at knowledge boundaries.

Do not make AD/LDAP/Entra groups a Markitect core dependency.

Instead:

  1. Accept NetKingdom/key-cape-compatible OIDC tokens.
  2. Normalize claims into PolicySubject.
  3. Map enterprise groups/roles/scopes to Markitect labels/trust zones/actions.
  4. Use the existing AccessPolicyGateway as the enforcement point.
  5. Let OpenFGA/SpiceDB/OPA/Cedar attach through adapter protocols where a deployment needs stronger central policy.
  6. Persist decisions before using this for production agent memory or exports.

flex-auth Boundary

The preferred long-term shape is a separate flex-auth service/repo under the NetKingdom authorization umbrella. In that model, Markitect remains a resource consumer and policy enforcement point. flex-auth owns the central resource registry, enterprise group/role/scope mapping, external PDP adapters, and durable decision logs.

The product survey, Keycloak/Entra analysis, and boundary recommendation now live in the sibling flex-auth repo: flex-auth/docs/flex-auth-authorization-registry-research.md.

Implementation follow-up is tracked there:

  • FLEX-WP-0002: standalone policy-as-code core and check APIs.
  • FLEX-WP-0003: flex-auth service-side Markitect consumer integration.
  • FLEX-WP-0004: delegated PDP and directory adapters.

Markitect should not implement a live flex-auth service client until FLEX-WP-0003 stabilizes the resource-registration and check/batch_check API.

Sources