generated from coulomb/repo-seed
Enterprise access control integration
This commit is contained in:
@@ -139,6 +139,22 @@ to future backend storage.
|
||||
|
||||
## Adapter Boundaries
|
||||
|
||||
Enterprise IAM integration is covered in
|
||||
`docs/enterprise-access-control-integration.md`. In that architecture,
|
||||
Markitect is the policy enforcement point for Markdown knowledge results, while
|
||||
NetKingdom/key-cape-compatible OIDC supplies identity claims and external
|
||||
policy engines can act as policy decision points.
|
||||
|
||||
Identity and directory integration use these provider-neutral boundaries:
|
||||
|
||||
- `IdentityClaimsAdapter` validates OIDC/JWT/SAML material and returns
|
||||
normalized `EnterpriseIdentity`.
|
||||
- `DirectoryGroupResolver` resolves group overage or stale directory claims
|
||||
through SCIM/Graph/LDAP/Keycloak-style adapters.
|
||||
- `EnterprisePolicyMapper` maps canonical enterprise roles, scopes, and groups
|
||||
to `PolicySubject` labels, trust zones, and allowed actions.
|
||||
- `DecisionLogStore` persists durable audit records for policy decisions.
|
||||
|
||||
Relationship policies use `RelationshipPolicyAdapter`:
|
||||
|
||||
```text
|
||||
|
||||
335
docs/enterprise-access-control-integration.md
Normal file
335
docs/enterprise-access-control-integration.md
Normal file
@@ -0,0 +1,335 @@
|
||||
# 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:
|
||||
|
||||
```text
|
||||
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
|
||||
|
||||
```mermaid
|
||||
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:
|
||||
|
||||
```text
|
||||
directory groups -> canonical roles/scopes/trust labels -> Markitect subject
|
||||
```
|
||||
|
||||
Avoid:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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.
|
||||
|
||||
## Canonical Subject Mapping
|
||||
|
||||
Recommended normalized shape:
|
||||
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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]
|
||||
```
|
||||
|
||||
## Data/Object Mapping
|
||||
|
||||
Markdown remains the source-friendly object labeling layer:
|
||||
|
||||
```yaml
|
||||
---
|
||||
policy:
|
||||
labels: [internal]
|
||||
trust_zone: internal
|
||||
owner: team:platform-architecture
|
||||
---
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Recommended Direction
|
||||
|
||||
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.
|
||||
|
||||
## Sources
|
||||
|
||||
- OpenID Connect Core 1.0: https://openid.net/specs/openid-connect-core-1_0.html
|
||||
- OAuth 2.0 Token Exchange, RFC 8693: https://www.rfc-editor.org/rfc/rfc8693
|
||||
- SCIM Protocol, RFC 7644: https://datatracker.ietf.org/doc/rfc7644
|
||||
- NIST SP 800-162 ABAC guide: https://csrc.nist.gov/pubs/sp/800/162/upd2/final
|
||||
- NIST glossary, Policy Enforcement Point:
|
||||
https://csrc.nist.gov/glossary/term/policy_enforcement_point
|
||||
- NIST glossary, Policy Decision Point:
|
||||
https://csrc.nist.gov/glossary/term/policy_decision_point
|
||||
- NIST glossary, Policy Information Point:
|
||||
https://csrc.nist.gov/glossary/term/policy_information_point
|
||||
- Keycloak Server Administration Guide: https://www.keycloak.org/docs/latest/server_admin/
|
||||
- Microsoft Entra group claims: https://learn.microsoft.com/en-us/security/zero-trust/develop/configure-tokens-group-claims-app-roles
|
||||
- OpenFGA concepts: https://openfga.dev/docs/concepts
|
||||
- Open Policy Agent policy language: https://www.openpolicyagent.org/docs/policy-language
|
||||
- Cedar policy language: https://docs.cedarpolicy.com/
|
||||
- Local canon: `/home/worsch/the-custodian/canon/standards/iam-profile_v0.1.md`
|
||||
@@ -38,6 +38,7 @@ and descriptions mirror the operational view.
|
||||
| `MKTT-WP-0005` | complete | done | `MKTT-WP-0003`, `MKTT-WP-0004` | Runtime context, form state, dynamic rules, workflow integration, and provider-neutral assessment boundary are complete. |
|
||||
| `MKTT-WP-0011` | complete | done | `MKTT-WP-0003`; task-level triggers: `MKTT-WP-0010-T001`, `MKTT-WP-0010-T005` | Markdown dataflow workflow layer is complete: workflow standard, source collectors, binding model, deterministic steps, assisted boundary, safe outputs, CLI, docs, and examples. |
|
||||
| `MKTT-WP-0009` | complete | done | `MKTT-WP-0006` | Access-controlled knowledge gateway is complete: local labels, trust zones, path rules, policy-aware cache query/search, decisions, diagnostics, and external adapter boundaries. |
|
||||
| `MKTT-WP-0014` | P2 | todo | `MKTT-WP-0009` | Enterprise IAM access-control integration: NetKingdom/key-cape-compatible identity claims, directory group resolution, policy maps, durable decision logs, and external PDP examples. |
|
||||
| `MKTT-WP-0012` | P3 | todo | `MKTT-WP-0004`, `MKTT-WP-0010`, `MKTT-WP-0011` | Future Quarkdown-inspired document function layer: reusable Markdown-native function calls over processors, references, contracts, workflows, and later assisted steps. |
|
||||
| `MKTT-WP-0008` | P3 | todo | `MKTT-WP-0006`, `MKTT-WP-0007`, `MKTT-WP-0009` | Agent working-memory cache after backend and policy floor are available. |
|
||||
|
||||
@@ -74,6 +75,12 @@ operations deserve author-facing function syntax. It should remain optional and
|
||||
capability-gated, especially before assisted, external, file, or network
|
||||
functions are allowed.
|
||||
|
||||
`MKTT-WP-0014` captures enterprise IAM integration for the access-control
|
||||
gateway. It should follow `MKTT-WP-0009` and can run before or alongside
|
||||
security-sensitive context memory work. It does not block local `MKTT-WP-0008`
|
||||
research, but it should gate production deployment of reactivatable agent
|
||||
context packages in enterprise environments.
|
||||
|
||||
## State Hub Mirror
|
||||
|
||||
Native State Hub dependency edges should mirror the whole-workstream
|
||||
@@ -100,6 +107,7 @@ dependencies:
|
||||
- `MKTT-WP-0012 -> MKTT-WP-0004`
|
||||
- `MKTT-WP-0012 -> MKTT-WP-0010`
|
||||
- `MKTT-WP-0012 -> MKTT-WP-0011`
|
||||
- `MKTT-WP-0014 -> MKTT-WP-0009`
|
||||
- `MKTT-WP-0008 -> MKTT-WP-0006`
|
||||
- `MKTT-WP-0008 -> MKTT-WP-0007`
|
||||
- `MKTT-WP-0008 -> MKTT-WP-0009`
|
||||
|
||||
Reference in New Issue
Block a user