mirror of
https://github.com/mcloh/Enterprise-MCP-Service-Bus.git
synced 2026-11-05 22:14:11 +00:00
130 lines
8.1 KiB
Markdown
130 lines
8.1 KiB
Markdown
# Assumptions — assumptions and decisions of this RI
|
|
|
|
This document explains **what was assumed** when building the Reference Implementation (RI) and
|
|
**why**, distinguishing that from what is an architectural guarantee of the [reference
|
|
architecture](../README.md). It is a synthesis — not a copy — of the decision history recorded
|
|
in [`docs/adr/`](../../docs/adr/); each ADR remains the canonical record of an individual
|
|
decision, this document groups the "why" by theme for whoever is evaluating the RI.
|
|
|
|
Target audience: whoever is going to **evaluate or adapt** this RI for a real scenario and needs
|
|
to know what was assumed versus what is a guarantee of the architecture.
|
|
|
|
## General scope
|
|
|
|
**We assume that an RI proves security properties, it is not a production-ready product.**
|
|
Every decision below prioritizes verifiably demonstrating the architecture's invariants
|
|
(`MaximumEntitlement` as a ceiling, fail-closed, never elevate privilege by context) over
|
|
operational completeness (HA, scale, UI). Where the two collided, we chose the simplest RI
|
|
that still proves the real property against a real dependency — never a mock of the very
|
|
point being tested.
|
|
|
|
## Identity and PDP: closed technologies, not hypotheses to revisit
|
|
|
|
**We assume Keycloak as Identity Provider and OPA/Rego as PDP because they are OSS (Apache-2.0)
|
|
and adherent to open standards** (OAuth 2.1/OIDC, Rego), not out of arbitrary preference. This
|
|
resolves two gaps that the reference architecture left open (`README.md` §48, questions
|
|
1 and 3) with a definitive technical decision, not an assumption — they were never revisited
|
|
throughout the implementation. See `docs/adr/ADR-019-extensao-de-identidade.md`,
|
|
`docs/adr/ADR-025-engine-do-pdp.md`.
|
|
|
|
**We rejected** a custom PDP engine in Python (more control, but reinvents policy evaluation
|
|
with no real gain) and Cedar (also would be adequate, but OPA has greater adherence to "open
|
|
standards" and a more mature Rego community for the scope of this RI).
|
|
|
|
## Operational reference Python/LangGraph/Langfuse (Agent Platform OCI)
|
|
|
|
**We assume as the concrete operational reference the Agent Platform OCI project by Christiano
|
|
Hoshikawa** (`docs/research/hoshikawa-agent-platform-oci.md`) for the
|
|
LangGraph/Langfuse/FastMCP layer, instead of inventing a generic pattern from scratch — faster,
|
|
fewer ad hoc decisions, and a real point of comparison for what "multiagent orchestration"
|
|
means in practice. **We reuse** from that reference: `StateGraph` with a router/supervisor per
|
|
backend, pluggable checkpointing, the IC/NOC/GRL observability taxonomy with hybrid
|
|
instrumentation (automatic spans + fail-open manual events), `identity.yaml`/`BusinessContext`
|
|
to normalize identity across channels, FastMCP as the MCP server standard.
|
|
|
|
**We explicitly rejected** a single element of that reference: its tool authorization model via
|
|
a static allowlist evaluated over an `agent_id` that arrives as **data from the conversation's
|
|
input payload**, not as a claim from an independently verified authenticated identity — the
|
|
reference project itself admits that this does not replace real authentication/authorization.
|
|
That is exactly the anti-pattern form that the architecture forbids
|
|
(`ADR-001`/`ADR-002`/`ADR-003`). The RI reuses the proxy *shape* of that Gateway
|
|
(invocation/result contracts, per-tool cache, catalog) only at the Fabric/conversational UX
|
|
layer — the ALLOW/DENY decision remains 100% in our PEP/PDP, never in a self-declared
|
|
`agent_id`. See `docs/adr/ADR-022-referencia-hoshikawa-agent-platform-oci.md`,
|
|
`docs/adr/ADR-023-autorizacao-nunca-vem-do-payload.md`. This finding also motivated a dedicated
|
|
adversarial scenario (`tests/adversarial/test_payload_identity_spoofing.py`).
|
|
|
|
## Downstream identity
|
|
|
|
**We assume** token exchange (RFC 8693) when the backend supports OIDC, with a fallback to a
|
|
service account isolated per adapter when it does not — because always reusing the client's
|
|
token (the simpler alternative) is exactly the "blind token passthrough" that the architecture
|
|
forbids (inbound ≠ outbound identity). See `docs/adr/ADR-020-downstream-identity.md`.
|
|
|
|
## Client profile granularity
|
|
|
|
**We assume** domain + risk tier (e.g.: `Sales.Read`=R1, `Sales.Write`=R2,
|
|
`Finance.Payments`=R3) as the client profile granularity, instead of a single "enterprise
|
|
admin" client or domain-only without tier — because only this granularity allows proving
|
|
blast-radius segmentation between risk tiers within the same domain (README.md §7, §17,
|
|
§31). See `docs/adr/ADR-008-segmentacao-por-dominio-e-risco.md`.
|
|
|
|
## Profile Intelligence: deterministic stub, not "real AI"
|
|
|
|
**We assume** that "generic and replaceable" Profile Intelligence (README.md §6.10) does not
|
|
prescribe an algorithm, taxonomy, or real data source — because the reference architecture does
|
|
not define any of these, deliberately. The RI implements a stub based on deterministic rules
|
|
over synthetic attributes, behind a replaceable interface (`ProfileIntelligenceProvider`),
|
|
which fulfills the **contract**, not the "intelligence" itself. A production fork replaces only
|
|
the implementation, never the contract (`ProfileView`) nor the point where it connects (never
|
|
to the PDP).
|
|
|
|
## Domain scope: two, not full federation
|
|
|
|
**We assume** two example domains (Sales, Finance) as sufficient to prove
|
|
segmentation/blast-radius between distinct domains, without needing full multi-domain
|
|
federation. Federation is deliberately out of scope for this RI — it is addressed in the
|
|
reference architecture's roadmap as a later phase (§47, Phase 5), not an implementation gap.
|
|
|
|
## Environment: 100% local via Docker Compose
|
|
|
|
**We assume** that an RI runs entirely locally via `docker compose`, with environment
|
|
separation demonstrated by a configuration overlay (`config/env/{dev,ci}.yaml`) instead of
|
|
real cloud/hybrid infrastructure — proving the architecture does not require multi-cloud, and
|
|
simulating multi-cloud without real multi-cloud would prove nothing beyond the simulation
|
|
itself.
|
|
|
|
## Substitutions to enable testing without heavy infrastructure
|
|
|
|
- **Local JWKS server as a stand-in for Keycloak** in most of the e2e suite — valid because
|
|
what is being tested there is the *token validation logic* (signature, `exp`, `iss`,
|
|
`aud`, extraction of `azp`), which is identical against any valid RS256 JWKS. Real protocol
|
|
integration with Keycloak (`client_credentials` grant, real claims issued by a real IdP,
|
|
RFC 8693) is covered separately, against a real Keycloak 26.7.3 via Docker
|
|
(`tests/e2e/test_real_keycloak.py`) — it is not the same test, it is a complementary test
|
|
that covers exactly what the stand-in cannot.
|
|
- **SQLite instead of Postgres** for the Registry and for the LangGraph checkpointer — valid to
|
|
prove the contract/behavior (schema, lifecycle, graph pause/resume); it is not a claim
|
|
about performance or concurrency under production load (see
|
|
`Production-Recommendations.md`).
|
|
- **`policy_version` as a file hash, not a real OPA bundle revision** — a SHA-256 of the
|
|
content of the `.rego` files on disk is enough to prove that `policy_version` flows end to
|
|
end through every decision and audit event; it is not a claim about policy distribution in a
|
|
production cluster.
|
|
|
|
## Items deliberately out of scope
|
|
|
|
- **REST adapter without a live path through the Gateway** (EP-06-T04): implemented and tested
|
|
standalone; none of this RI's example backends is REST, so there is no live path through the
|
|
Gateway exercising it. It would only become relevant if a future domain needed a
|
|
non-MCP-native backend.
|
|
- **LangGraph deliberately absent from the Gateway/Fabric** — used only where there is real
|
|
state, cycles, or checkpointing (Service Orchestrator, EP-11; Agent Runtime handoff, EP-12-T03).
|
|
No simple routing (Gateway EP-05, Fabric EP-06, Offering Filter EP-10) uses LangGraph —
|
|
using a stateful graph for stateless routing would be over-engineering, not a neutral choice.
|
|
See `docs/adr/ADR-021-escopo-langgraph-langfuse.md`.
|
|
- **Rate limiting and anti-replay**: real, conscious gaps, not oversights — documented and
|
|
covered by a dedicated adversarial test (`tests/adversarial/test_protocol_identity.py`), never
|
|
silently ignored. See `Production-Recommendations.md` for what a real deployment needs to
|
|
add.
|