From 6f9699b51a2ad3eea360771b6d4789c18e82f90b Mon Sep 17 00:00:00 2001 From: Jason Walker <913443@dadeschools.net> Date: Thu, 2 Jul 2026 15:22:43 -0400 Subject: [PATCH] docs: extend profile model for multi-service MCP boundaries (#76) --- .../multi-service-profile-model.md | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 docs/architecture/multi-service-profile-model.md diff --git a/docs/architecture/multi-service-profile-model.md b/docs/architecture/multi-service-profile-model.md new file mode 100644 index 0000000..0e1c627 --- /dev/null +++ b/docs/architecture/multi-service-profile-model.md @@ -0,0 +1,68 @@ +# Multi-Service MCP Profile and Configuration Model + +- **Status:** Design (no implementation in this repo yet) +- **Issue:** #76 (parent umbrella: #75; boundary decision: ADR-0001, #71) +- **Date:** 2026-07-02 + +## 1. Purpose and Scope + +Extend the existing Gitea execution-profile model (`docs/gitea-execution-profiles.md`) into a generic **per-service** MCP profile/config model. This supports integrating Jenkins and GlitchTip into the MCP Control Plane while strictly preserving isolation and fail-closed safety. + +**Crucial Constraints:** +* The shared profile/config model is a **schema / library**, **not a shared credential pool**. +* Tokens remain **service-local**; profiles are **per service**. +* Orchestrators **must not** directly hold every service credential. + +## 2. Profile Schema (Per Service) + +The schema reuses the proven Gitea field model, adapted per service. + +```json +{ + "profile_name": "readonly-metrics", + "service": "glitchtip", + "token_source_name": "GLITCHTIP_API_TOKEN_READONLY", + "allowed_operations": [ + "glitchtip.event.read", + "glitchtip.issue.read" + ], + "forbidden_operations": [ + "glitchtip.issue.resolve", + "glitchtip.issue.delete" + ] +} +``` + +### Schema Rules + +* `allowed_operations` are **namespaced** (e.g., `gitea.issue.create`, `jenkins.build.read`, `glitchtip.event.read`). +* `forbidden_operations`, if present, **always override** `allowed_operations`. +* `token_source_name` records the source **name only, never the value**. Tokens must never be printed, logged, or included in telemetry. + +## 3. Fail-Closed Behavior + +The model enforces strict fail-closed constraints before any network call occurs: +* **Missing Profile:** If a requested profile is undefined for the target service, the operation fails immediately. +* **Missing Credentials:** If the `token_source_name` cannot be resolved to a valid token at runtime, the operation fails immediately without retrying or prompting. + +## 4. Environment Overrides + +Profiles can be dynamically overridden or injected via environment variables, following the established hierarchy: + +1. **Explicit Environment Variable:** (Highest precedence) e.g., `MCP_GLITCHTIP_TOKEN` overrides any JSON profile. +2. **Profile Mapping in JSON:** Resolved via `token_source_name` (e.g., `GLITCHTIP_API_TOKEN_READONLY`) mapping to an environment variable or secret store. +3. **No Auth:** Fails closed. + +## 5. Audit Logging + +To maintain accountability across multi-service workflows, all mutating actions must include the audit identity and source: +* The audit log must record the `profile_name`, the orchestrator source (e.g., `sysadmin`, `jenkins-mcp`), and the action taken. +* The audit system must sanitize all output to ensure tokens are stripped (see `safety-model.md`). + +## 6. Backward Compatibility + +The existing Gitea profile behavior (`gitea_whoami`, etc.) remains strictly backward compatible. The generic profile library will parse existing Gitea profile objects without requiring them to migrate their schemas, defaulting the `service` attribute to `gitea`. + +## 7. Implementation Boundary + +Per the namespace decisions in #71 and #75, this generic model belongs in the `common` package or library. It will be imported by `gitea-mcp` (this repo), `jenkins-mcp`, and `glitchtip-mcp` without forcing a monolithic architecture.