mirror of
https://github.com/mcloh/Enterprise-MCP-Service-Bus.git
synced 2026-11-06 06:24:12 +00:00
revisão e complementação da documentação do projeto
This commit is contained in:
65
RI/docs/interfaces/identity-oidc.en-us.md
Normal file
65
RI/docs/interfaces/identity-oidc.en-us.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Interface: MCP Client identity and registration (OIDC)
|
||||
|
||||
Contract for registering an MCP Client and the OIDC token it presents to the Gateway.
|
||||
Implementation: [`src/emcp_bus/identity/models.py`](../../src/emcp_bus/identity/models.py),
|
||||
[`identity/authn.py`](../../src/emcp_bus/identity/authn.py),
|
||||
[`identity/shared_client_lint.py`](../../src/emcp_bus/identity/shared_client_lint.py). See
|
||||
[`AS-BUILT.md`](../AS-BUILT.md#identidade-do-mcp-client-ep-01).
|
||||
|
||||
## Registering an MCP Client
|
||||
|
||||
One YAML file per client in `config/clients/*.yaml`, validated against `ClientRegistration`:
|
||||
|
||||
```yaml
|
||||
client_id: finance-payments-agent # exactly the token's azp/client_id claim
|
||||
profile: Finance.Payments # name of a ClientProfile under config/clients/profiles/
|
||||
environment: production # "dev" | "ci" | "production"
|
||||
description: "Finance agent authorized to create/execute payments (R3, approval above threshold)"
|
||||
```
|
||||
|
||||
(real example: `config/clients/finance-payments-agent.yaml`)
|
||||
|
||||
`client_id` is the sole link between an authenticated identity and a `ClientProfile` — two
|
||||
distinct `client_id`s never share a `profile` unless that is an explicit and auditable decision
|
||||
(the shared-client rule, `identity/shared_client_lint.py`, wired into
|
||||
`make validate-schemas`).
|
||||
|
||||
## Registering the client with the IdP
|
||||
|
||||
The client must exist in the IdP realm with the `client_credentials` grant enabled and an
|
||||
audience mapper pointing at the Gateway's `OIDC_AUDIENCE` (`emcp-gateway` by default). See
|
||||
`deploy/keycloak/realm-export.json` for the 3 example clients already configured this way
|
||||
(`sales-read-agent`, `sales-write-agent`, `finance-payments-agent`).
|
||||
|
||||
## Access token contract
|
||||
|
||||
Any OIDC-compliant IdP works (`TokenValidator` is provider-agnostic). Claims required and
|
||||
validated by `TokenValidator.validate`:
|
||||
|
||||
| Claim | Use |
|
||||
|---|---|
|
||||
| `exp` | Expiration — required, validated with `leeway_seconds=5`. |
|
||||
| `iss` | Must match `OIDC_ISSUER` exactly. |
|
||||
| `aud` | Must contain `OIDC_AUDIENCE`. |
|
||||
| `azp` (preferred) or `client_id` | Sole source of client identity — never `clientInfo` from the MCP request nor any body field. |
|
||||
|
||||
Signature verified via JWKS (`OIDC_JWKS_URL`), `RS256` algorithm. Failure of any check raises
|
||||
`AuthenticationError`, treated by the Gateway as `UNAUTHENTICATED` (fail-closed).
|
||||
|
||||
## How a new client registers, end to end
|
||||
|
||||
1. Create/update the client in the IdP (`client_credentials` grant, audience mapper).
|
||||
2. Create `config/clients/<client-id>.yaml` (`ClientRegistration`).
|
||||
3. Point `profile` at an existing `ClientProfile`, or create a new one under
|
||||
`config/clients/profiles/` (see [`registry-capability-manifest.md`](registry-capability-manifest.md)
|
||||
for how a capability references a profile via `entitlements`).
|
||||
4. `make validate-schemas`.
|
||||
5. Restart the Gateway (client registrations are loaded at boot, no hot-reload).
|
||||
|
||||
## Errors
|
||||
|
||||
| Situation | Behavior |
|
||||
|---|---|
|
||||
| Missing/malformed/expired token or invalid signature | `AuthenticationError` → Gateway treats it as `UNAUTHENTICATED`. |
|
||||
| Incorrect `aud`/`iss` | `AuthenticationError` → `UNAUTHENTICATED` (README.md §45 Test 8). |
|
||||
| Valid token, but `client_id` without a matching `ClientRegistration` | `UnknownClientError` → Gateway responds `UNKNOWN_CLIENT` on `tools/call`, empty list on `tools/list`. |
|
||||
Reference in New Issue
Block a user