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.md
Normal file
65
RI/docs/interfaces/identity-oidc.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Interface: identidade e registro de MCP Client (OIDC)
|
||||
|
||||
Contrato de registro de um MCP Client e do token OIDC que ele apresenta ao Gateway.
|
||||
Implementação: [`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). Ver
|
||||
[`AS-BUILT.md`](../AS-BUILT.md#identidade-do-mcp-client-ep-01).
|
||||
|
||||
## Registro de um MCP Client
|
||||
|
||||
Um arquivo YAML por client em `config/clients/*.yaml`, validado contra `ClientRegistration`:
|
||||
|
||||
```yaml
|
||||
client_id: finance-payments-agent # exatamente a claim azp/client_id do token
|
||||
profile: Finance.Payments # nome de um ClientProfile em config/clients/profiles/
|
||||
environment: production # "dev" | "ci" | "production"
|
||||
description: "Finance agent authorized to create/execute payments (R3, approval above threshold)"
|
||||
```
|
||||
|
||||
(exemplo real: `config/clients/finance-payments-agent.yaml`)
|
||||
|
||||
`client_id` é o único vínculo entre uma identidade autenticada e um `ClientProfile` — dois
|
||||
`client_id`s distintos nunca compartilham `profile` a menos que isso seja uma decisão explícita
|
||||
e auditável (regra de shared client, `identity/shared_client_lint.py`, ligada a
|
||||
`make validate-schemas`).
|
||||
|
||||
## Registro do client no IdP
|
||||
|
||||
O client precisa existir no realm do IdP com o grant `client_credentials` habilitado e um
|
||||
mapper de audience apontando para o `OIDC_AUDIENCE` do Gateway (`emcp-gateway` por padrão). Ver
|
||||
`deploy/keycloak/realm-export.json` para os 3 clients de exemplo já configurados dessa forma
|
||||
(`sales-read-agent`, `sales-write-agent`, `finance-payments-agent`).
|
||||
|
||||
## Contrato do token de acesso
|
||||
|
||||
Qualquer IdP compatível com OIDC funciona (`TokenValidator` é agnóstico de fornecedor). Claims
|
||||
exigidas e validadas por `TokenValidator.validate`:
|
||||
|
||||
| Claim | Uso |
|
||||
|---|---|
|
||||
| `exp` | Expiração — obrigatória, validada com `leeway_seconds=5`. |
|
||||
| `iss` | Deve casar exatamente com `OIDC_ISSUER`. |
|
||||
| `aud` | Deve conter `OIDC_AUDIENCE`. |
|
||||
| `azp` (preferencial) ou `client_id` | Fonte única de identidade do client — nunca `clientInfo` do request MCP nem qualquer campo do corpo. |
|
||||
|
||||
Assinatura verificada via JWKS (`OIDC_JWKS_URL`), algoritmo `RS256`. Falha em qualquer checagem
|
||||
levanta `AuthenticationError`, tratada pelo Gateway como `UNAUTHENTICATED` (fail-closed).
|
||||
|
||||
## Como um novo client se registra, ponta a ponta
|
||||
|
||||
1. Criar/atualizar o client no IdP (grant `client_credentials`, mapper de audience).
|
||||
2. Criar `config/clients/<client-id>.yaml` (`ClientRegistration`).
|
||||
3. Apontar `profile` para um `ClientProfile` existente, ou criar um novo em
|
||||
`config/clients/profiles/` (ver [`registry-capability-manifest.md`](registry-capability-manifest.md)
|
||||
para como uma capability referencia um profile via `entitlements`).
|
||||
4. `make validate-schemas`.
|
||||
5. Reiniciar o Gateway (registros de client são carregados no boot, sem hot-reload).
|
||||
|
||||
## Erros
|
||||
|
||||
| Situação | Comportamento |
|
||||
|---|---|
|
||||
| Token ausente/malformado/expirado/assinatura inválida | `AuthenticationError` → Gateway trata como `UNAUTHENTICATED`. |
|
||||
| `aud`/`iss` incorretos | `AuthenticationError` → `UNAUTHENTICATED` (README.md §45 Teste 8). |
|
||||
| Token válido, mas `client_id` sem `ClientRegistration` correspondente | `UnknownClientError` → Gateway responde `UNKNOWN_CLIENT` em `tools/call`, lista vazia em `tools/list`. |
|
||||
Reference in New Issue
Block a user