Merge pull request 'docs: extend profile model for multi-service MCP boundaries (#76)' (#92) from docs/issue-76-multi-service-profile-model into master

This commit was merged in pull request #92.
This commit is contained in:
2026-07-02 14:44:35 -05:00
@@ -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.