mirror of
https://github.com/hoshikawa2/agent_platform_oci.git
synced 2026-09-07 18:23:46 +00:00
988 lines
20 KiB
Markdown
988 lines
20 KiB
Markdown
# Implementando Basic Auth
|
|
|
|
Para validar **todo o circuito com Basic Auth**, você precisa configurar três relações distintas:
|
|
|
|
```text
|
|
Cliente de teste
|
|
└─ Basic Auth A ─► Agent Gateway :8010
|
|
└─ Basic Auth B ─► Agent Backend :8000
|
|
└─ Basic Auth C ─► MCP Gateway :8300
|
|
```
|
|
|
|
Há um detalhe importante: no pacote atual, a autenticação Basic já funciona para chamadas **de entrada**, mas os clientes internos ainda não enviam Basic Auth:
|
|
|
|
* `Agent Gateway → Agent Backend` não envia credencial;
|
|
* `Agent Backend → MCP Gateway` envia apenas Bearer Token.
|
|
|
|
Portanto, para testar o circuito inteiro com Basic Auth, faça os dois pequenos ajustes de código descritos abaixo.
|
|
|
|
---
|
|
|
|
# 1. Preparar o ambiente
|
|
|
|
Considere que o ZIP foi extraído em:
|
|
|
|
```bash
|
|
cd agent_framework_oci_authentication_v2_1
|
|
```
|
|
|
|
Crie um único ambiente virtual para facilitar o teste:
|
|
|
|
```bash
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
```
|
|
|
|
No Windows PowerShell:
|
|
|
|
```powershell
|
|
python -m venv .venv
|
|
.\.venv\Scripts\Activate.ps1
|
|
```
|
|
|
|
Instale o framework e as dependências dos três componentes:
|
|
|
|
```bash
|
|
pip install -U pip
|
|
|
|
pip install -e ./libs/agent_framework
|
|
|
|
pip install \
|
|
-r ./Tuning-Performance/Authentication/agent_template_backend_authentication/requirements.txt \
|
|
-r ./apps/agent_gateway/requirements.txt \
|
|
-r ./apps/mcp_gateway/requirements.txt
|
|
```
|
|
|
|
Confirme a importação:
|
|
|
|
```bash
|
|
python -c "from agent_framework.security import install_authentication; print('framework ok')"
|
|
```
|
|
|
|
---
|
|
|
|
# 2. Criar três pares de Client ID e Secret
|
|
|
|
Use credenciais diferentes para cada trecho. Para teste local:
|
|
|
|
| Fluxo | Client ID | Secret de teste |
|
|
| ----------------------- | -------------------- | --------------------------- |
|
|
| Cliente → Agent Gateway | `tia-test` | `TiaGateway-Test-2026!` |
|
|
| Agent Gateway → Backend | `agent-gateway-test` | `GatewayBackend-Test-2026!` |
|
|
| Backend → MCP Gateway | `agent-backend-test` | `BackendMcp-Test-2026!` |
|
|
|
|
Esses valores são apenas para ambiente local. Não os reutilize em produção.
|
|
|
|
## Gerar os hashes
|
|
|
|
O script está em:
|
|
|
|
```text
|
|
Tuning-Performance/Authentication/
|
|
agent_template_backend_authentication/
|
|
scripts/generate_secret_hash.py
|
|
```
|
|
|
|
Execute:
|
|
|
|
```bash
|
|
python Tuning-Performance/Authentication/agent_template_backend_authentication/scripts/generate_secret_hash.py \
|
|
--secret 'TiaGateway-Test-2026!'
|
|
```
|
|
|
|
Depois:
|
|
|
|
```bash
|
|
python Tuning-Performance/Authentication/agent_template_backend_authentication/scripts/generate_secret_hash.py \
|
|
--secret 'GatewayBackend-Test-2026!'
|
|
```
|
|
|
|
E:
|
|
|
|
```bash
|
|
python Tuning-Performance/Authentication/agent_template_backend_authentication/scripts/generate_secret_hash.py \
|
|
--secret 'BackendMcp-Test-2026!'
|
|
```
|
|
|
|
Você receberá três valores semelhantes a:
|
|
|
|
```text
|
|
pbkdf2_sha256:310000:<salt>:<digest>
|
|
```
|
|
|
|
Guarde-os temporariamente:
|
|
|
|
```bash
|
|
HASH_CLIENT_GATEWAY='pbkdf2_sha256:310000:...'
|
|
HASH_GATEWAY_BACKEND='pbkdf2_sha256:310000:...'
|
|
HASH_BACKEND_MCP='pbkdf2_sha256:310000:...'
|
|
```
|
|
|
|
O hash muda a cada execução porque o salt é aleatório. Isso é esperado.
|
|
|
|
---
|
|
|
|
# 3. Configurar o Agent Gateway
|
|
|
|
Entre no diretório:
|
|
|
|
```bash
|
|
cd apps/agent_gateway
|
|
```
|
|
|
|
Copie o exemplo:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Adicione ao final do `.env`:
|
|
|
|
```env
|
|
# Entrada: cliente/TIA -> Agent Gateway
|
|
AGENT_GATEWAY_AUTH_ENABLED=true
|
|
AGENT_GATEWAY_AUTH_MODE=basic
|
|
AGENT_GATEWAY_AUTH_BASIC_CLIENT_ID=tia-test
|
|
AGENT_GATEWAY_AUTH_BASIC_SECRET_HASH=COLE_AQUI_HASH_CLIENT_GATEWAY
|
|
AGENT_GATEWAY_AUTH_BASIC_REALM=agent-gateway
|
|
|
|
AGENT_GATEWAY_AUTH_PUBLIC_PATHS=/health,/docs,/openapi.json,/redoc
|
|
AGENT_GATEWAY_AUTH_PUBLIC_PREFIXES=
|
|
|
|
# Saída: Agent Gateway -> Agent Backend
|
|
BACKEND_AUTH_MODE=basic
|
|
BACKEND_AUTH_CLIENT_ID=agent-gateway-test
|
|
BACKEND_AUTH_SECRET=GatewayBackend-Test-2026!
|
|
```
|
|
|
|
Não coloque aspas no `.env`:
|
|
|
|
```env
|
|
BACKEND_AUTH_SECRET=GatewayBackend-Test-2026!
|
|
```
|
|
|
|
O arquivo de backends já aponta o backend Contas para:
|
|
|
|
```yaml
|
|
contas:
|
|
url: http://localhost:8000
|
|
```
|
|
|
|
Arquivo:
|
|
|
|
```text
|
|
apps/agent_gateway/config/backends.yaml
|
|
```
|
|
|
|
Para este teste, mantenha apenas o backend `contas` ou force o backend no payload. Caso contrário, pedidos sobre ofertas e suporte podem ser roteados para portas em que nenhum backend está rodando.
|
|
|
|
---
|
|
|
|
# 4. Fazer o Agent Gateway enviar Basic Auth ao backend
|
|
|
|
Abra:
|
|
|
|
```text
|
|
libs/agent_framework/src/agent_framework/global_supervisor/client.py
|
|
```
|
|
|
|
Substitua a classe `BackendClient` por uma versão que aceite autenticação Basic.
|
|
|
|
No início do arquivo, adicione:
|
|
|
|
```python
|
|
import os
|
|
```
|
|
|
|
Altere o construtor:
|
|
|
|
```python
|
|
class BackendClient:
|
|
def __init__(
|
|
self,
|
|
timeout_seconds: float = 120.0,
|
|
basic_client_id: str | None = None,
|
|
basic_secret: str | None = None,
|
|
):
|
|
self.timeout_seconds = timeout_seconds
|
|
self.basic_client_id = basic_client_id
|
|
self.basic_secret = basic_secret
|
|
|
|
def _auth(self) -> httpx.BasicAuth | None:
|
|
if self.basic_client_id and self.basic_secret:
|
|
return httpx.BasicAuth(
|
|
username=self.basic_client_id,
|
|
password=self.basic_secret,
|
|
)
|
|
return None
|
|
```
|
|
|
|
No método `call_message`, troque:
|
|
|
|
```python
|
|
resp = await client.post(url, json=payload)
|
|
```
|
|
|
|
por:
|
|
|
|
```python
|
|
resp = await client.post(
|
|
url,
|
|
json=payload,
|
|
auth=self._auth(),
|
|
)
|
|
```
|
|
|
|
No método `health`, você pode manter `/health` público. Caso queira enviar autenticação também, use:
|
|
|
|
```python
|
|
resp = await client.get(url, auth=self._auth())
|
|
```
|
|
|
|
Agora abra:
|
|
|
|
```text
|
|
apps/agent_gateway/app/main.py
|
|
```
|
|
|
|
Adicione:
|
|
|
|
```python
|
|
import os
|
|
```
|
|
|
|
Troque:
|
|
|
|
```python
|
|
backend_client = BackendClient(
|
|
timeout_seconds=settings.BACKEND_TIMEOUT_SECONDS
|
|
)
|
|
```
|
|
|
|
por:
|
|
|
|
```python
|
|
backend_client = BackendClient(
|
|
timeout_seconds=settings.BACKEND_TIMEOUT_SECONDS,
|
|
basic_client_id=os.getenv("BACKEND_AUTH_CLIENT_ID"),
|
|
basic_secret=os.getenv("BACKEND_AUTH_SECRET"),
|
|
)
|
|
```
|
|
|
|
Isso implementa:
|
|
|
|
```text
|
|
Agent Gateway → Agent Backend
|
|
Authorization: Basic base64(agent-gateway-test:GatewayBackend-Test-2026!)
|
|
```
|
|
|
|
---
|
|
|
|
# 5. Configurar o Agent Backend autenticado
|
|
|
|
Entre no diretório:
|
|
|
|
```bash
|
|
cd Tuning-Performance/Authentication/agent_template_backend_authentication
|
|
```
|
|
|
|
Copie o exemplo:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Ajuste a seção de autenticação:
|
|
|
|
```env
|
|
# Entrada: Agent Gateway -> Agent Backend
|
|
AGENT_AUTH_ENABLED=true
|
|
AGENT_AUTH_MODE=basic
|
|
AGENT_AUTH_BASIC_CLIENT_ID=agent-gateway-test
|
|
AGENT_AUTH_BASIC_SECRET_HASH=COLE_AQUI_HASH_GATEWAY_BACKEND
|
|
AGENT_AUTH_BASIC_REALM=agent-contas
|
|
|
|
AGENT_AUTH_PUBLIC_PATHS=/health,/docs,/openapi.json,/redoc
|
|
AGENT_AUTH_PUBLIC_PREFIXES=
|
|
```
|
|
|
|
Para usar o MCP Gateway:
|
|
|
|
```env
|
|
MCP_GATEWAY_ENABLED=true
|
|
MCP_GATEWAY_URL=http://localhost:8300
|
|
MCP_GATEWAY_TIMEOUT_SECONDS=60
|
|
|
|
# Saída: Agent Backend -> MCP Gateway
|
|
MCP_GATEWAY_AUTH_MODE=basic
|
|
MCP_GATEWAY_BASIC_CLIENT_ID=agent-backend-test
|
|
MCP_GATEWAY_BASIC_SECRET=BackendMcp-Test-2026!
|
|
```
|
|
|
|
Para evitar dependências externas durante o primeiro teste, configure também:
|
|
|
|
```env
|
|
LLM_PROVIDER=mock
|
|
ENABLE_LANGFUSE=false
|
|
ENABLE_ANALYTICS=false
|
|
|
|
SESSION_REPOSITORY_PROVIDER=memory
|
|
MEMORY_REPOSITORY_PROVIDER=memory
|
|
CHECKPOINT_REPOSITORY_PROVIDER=memory
|
|
CACHE_PROVIDER=memory
|
|
USAGE_REPOSITORY_PROVIDER=memory
|
|
```
|
|
|
|
Os nomes exatos de alguns providers podem depender do arquivo de configuração atual do framework. Caso o `.env.example` já contenha valores locais ou mock, preserve-os.
|
|
|
|
---
|
|
|
|
# 6. Fazer o Backend enviar Basic Auth ao MCP Gateway
|
|
|
|
Abra:
|
|
|
|
```text
|
|
libs/agent_framework/src/agent_framework/gateways/mcp_gateway_client.py
|
|
```
|
|
|
|
Substitua a implementação por:
|
|
|
|
```python
|
|
from __future__ import annotations
|
|
|
|
import base64
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
|
|
class MCPGatewayClient:
|
|
def __init__(
|
|
self,
|
|
base_url: str,
|
|
token: str | None = None,
|
|
timeout_seconds: int = 60,
|
|
auth_mode: str | None = None,
|
|
basic_client_id: str | None = None,
|
|
basic_secret: str | None = None,
|
|
):
|
|
self.base_url = base_url.rstrip("/")
|
|
self.token = token
|
|
self.timeout_seconds = timeout_seconds
|
|
self.auth_mode = (auth_mode or "").strip().lower()
|
|
self.basic_client_id = basic_client_id
|
|
self.basic_secret = basic_secret
|
|
|
|
def _headers(self) -> dict[str, str]:
|
|
if (
|
|
self.auth_mode == "basic"
|
|
and self.basic_client_id
|
|
and self.basic_secret
|
|
):
|
|
raw = f"{self.basic_client_id}:{self.basic_secret}".encode("utf-8")
|
|
encoded = base64.b64encode(raw).decode("ascii")
|
|
return {"Authorization": f"Basic {encoded}"}
|
|
|
|
if self.token:
|
|
return {"Authorization": f"Bearer {self.token}"}
|
|
|
|
return {}
|
|
|
|
async def list_tools(self) -> dict[str, Any]:
|
|
async with httpx.AsyncClient(
|
|
timeout=self.timeout_seconds
|
|
) as client:
|
|
response = await client.get(
|
|
f"{self.base_url}/v1/tools",
|
|
headers=self._headers(),
|
|
)
|
|
response.raise_for_status()
|
|
return response.json()
|
|
|
|
async def invoke_tool(
|
|
self,
|
|
*,
|
|
tenant_id: str,
|
|
agent_id: str,
|
|
channel: str | None,
|
|
tool_name: str,
|
|
arguments: dict[str, Any] | None = None,
|
|
business_context: dict[str, Any] | None = None,
|
|
metadata: dict[str, Any] | None = None,
|
|
) -> dict[str, Any]:
|
|
payload = {
|
|
"tenant_id": tenant_id,
|
|
"agent_id": agent_id,
|
|
"channel": channel,
|
|
"tool_name": tool_name,
|
|
"arguments": arguments or {},
|
|
"business_context": business_context or {},
|
|
"metadata": metadata or {},
|
|
}
|
|
|
|
async with httpx.AsyncClient(
|
|
timeout=self.timeout_seconds
|
|
) as client:
|
|
response = await client.post(
|
|
f"{self.base_url}/v1/tools/{tool_name}/invoke",
|
|
json=payload,
|
|
headers=self._headers(),
|
|
)
|
|
response.raise_for_status()
|
|
return response.json()
|
|
```
|
|
|
|
Agora abra:
|
|
|
|
```text
|
|
libs/agent_framework/src/agent_framework/mcp/tool_router.py
|
|
```
|
|
|
|
Localize:
|
|
|
|
```python
|
|
MCPGatewayClient(
|
|
base_url=getattr(
|
|
settings,
|
|
"MCP_GATEWAY_URL",
|
|
"http://localhost:8300",
|
|
),
|
|
token=getattr(settings, "MCP_GATEWAY_TOKEN", None),
|
|
timeout_seconds=getattr(
|
|
settings,
|
|
"MCP_GATEWAY_TIMEOUT_SECONDS",
|
|
settings.MCP_TOOL_TIMEOUT_SECONDS,
|
|
),
|
|
)
|
|
```
|
|
|
|
Altere para:
|
|
|
|
```python
|
|
MCPGatewayClient(
|
|
base_url=getattr(
|
|
settings,
|
|
"MCP_GATEWAY_URL",
|
|
"http://localhost:8300",
|
|
),
|
|
token=getattr(settings, "MCP_GATEWAY_TOKEN", None),
|
|
timeout_seconds=getattr(
|
|
settings,
|
|
"MCP_GATEWAY_TIMEOUT_SECONDS",
|
|
settings.MCP_TOOL_TIMEOUT_SECONDS,
|
|
),
|
|
auth_mode=getattr(
|
|
settings,
|
|
"MCP_GATEWAY_AUTH_MODE",
|
|
None,
|
|
),
|
|
basic_client_id=getattr(
|
|
settings,
|
|
"MCP_GATEWAY_BASIC_CLIENT_ID",
|
|
None,
|
|
),
|
|
basic_secret=getattr(
|
|
settings,
|
|
"MCP_GATEWAY_BASIC_SECRET",
|
|
None,
|
|
),
|
|
)
|
|
```
|
|
|
|
Adicione estes campos em:
|
|
|
|
```text
|
|
libs/agent_framework/src/agent_framework/config/settings.py
|
|
```
|
|
|
|
Próximo das configurações existentes de MCP Gateway:
|
|
|
|
```python
|
|
MCP_GATEWAY_AUTH_MODE: str | None = None
|
|
MCP_GATEWAY_BASIC_CLIENT_ID: str | None = None
|
|
MCP_GATEWAY_BASIC_SECRET: str | None = None
|
|
```
|
|
|
|
Há também uma factory local em:
|
|
|
|
```text
|
|
Tuning-Performance/Authentication/
|
|
agent_template_backend_authentication/
|
|
app/mcp_gateway_client_factory.py
|
|
```
|
|
|
|
Ajuste para:
|
|
|
|
```python
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
from agent_framework.gateways import MCPGatewayClient
|
|
|
|
|
|
def build_mcp_gateway_client() -> MCPGatewayClient | None:
|
|
if os.getenv("MCP_GATEWAY_ENABLED", "true").lower() != "true":
|
|
return None
|
|
|
|
return MCPGatewayClient(
|
|
base_url=os.getenv(
|
|
"MCP_GATEWAY_URL",
|
|
"http://localhost:8300",
|
|
),
|
|
token=os.getenv("MCP_GATEWAY_TOKEN") or None,
|
|
timeout_seconds=int(
|
|
os.getenv("MCP_GATEWAY_TIMEOUT_SECONDS", "60")
|
|
),
|
|
auth_mode=os.getenv("MCP_GATEWAY_AUTH_MODE"),
|
|
basic_client_id=os.getenv(
|
|
"MCP_GATEWAY_BASIC_CLIENT_ID"
|
|
),
|
|
basic_secret=os.getenv(
|
|
"MCP_GATEWAY_BASIC_SECRET"
|
|
),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
# 7. Configurar o MCP Gateway
|
|
|
|
Entre no diretório:
|
|
|
|
```bash
|
|
cd apps/mcp_gateway
|
|
```
|
|
|
|
Crie `.env`:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Adicione:
|
|
|
|
```env
|
|
# Entrada: Agent Backend -> MCP Gateway
|
|
MCP_GATEWAY_AUTH_ENABLED=true
|
|
MCP_GATEWAY_AUTH_MODE=basic
|
|
MCP_GATEWAY_AUTH_BASIC_CLIENT_ID=agent-backend-test
|
|
MCP_GATEWAY_AUTH_BASIC_SECRET_HASH=COLE_AQUI_HASH_BACKEND_MCP
|
|
MCP_GATEWAY_AUTH_BASIC_REALM=mcp-gateway
|
|
|
|
MCP_GATEWAY_AUTH_PUBLIC_PATHS=/health,/ready,/docs,/openapi.json,/redoc
|
|
MCP_GATEWAY_AUTH_PUBLIC_PREFIXES=
|
|
|
|
MCP_GATEWAY_CONFIG_PATH=config/mcp_gateway.yaml
|
|
```
|
|
|
|
## Desabilitar o mecanismo Bearer legado
|
|
|
|
O MCP Gateway ainda possui um segundo mecanismo antigo, configurado dentro de:
|
|
|
|
```text
|
|
apps/mcp_gateway/config/mcp_gateway.yaml
|
|
```
|
|
|
|
Localize a seção:
|
|
|
|
```yaml
|
|
auth:
|
|
enabled: true
|
|
```
|
|
|
|
Altere para:
|
|
|
|
```yaml
|
|
auth:
|
|
enabled: false
|
|
```
|
|
|
|
Isso é necessário porque o novo middleware já faz a autenticação Basic. Caso o `auth_check()` legado continue habilitado, a requisição passará pelo Basic e depois será rejeitada por não possuir Bearer Token.
|
|
|
|
---
|
|
|
|
# 8. Subir os componentes
|
|
|
|
Use quatro terminais.
|
|
|
|
## Terminal 1 — MCP Servers
|
|
|
|
O MCP Gateway precisa ter pelo menos um servidor MCP disponível para demonstrar uma chamada real.
|
|
|
|
Na raiz do projeto:
|
|
|
|
```bash
|
|
source .venv/bin/activate
|
|
```
|
|
|
|
Suba o servidor telecom:
|
|
|
|
```bash
|
|
uvicorn mcp.servers.telecom_mcp_server.main:app \
|
|
--host 0.0.0.0 \
|
|
--port 8100 \
|
|
--reload
|
|
```
|
|
|
|
Em outro terminal, caso queira também o retail:
|
|
|
|
```bash
|
|
uvicorn mcp.servers.retail_mcp_server.main:app \
|
|
--host 0.0.0.0 \
|
|
--port 8200 \
|
|
--reload
|
|
```
|
|
|
|
Confira as URLs configuradas em:
|
|
|
|
```text
|
|
apps/mcp_gateway/config/mcp_gateway.yaml
|
|
```
|
|
|
|
Para execução local, devem apontar para:
|
|
|
|
```yaml
|
|
url: http://localhost:8100
|
|
```
|
|
|
|
e:
|
|
|
|
```yaml
|
|
url: http://localhost:8200
|
|
```
|
|
|
|
---
|
|
|
|
## Terminal 2 — MCP Gateway
|
|
|
|
```bash
|
|
cd apps/mcp_gateway
|
|
source ../../.venv/bin/activate
|
|
```
|
|
|
|
Suba usando `--env-file`. Isso é importante porque o middleware lê variáveis com `os.getenv()`:
|
|
|
|
```bash
|
|
uvicorn app.main:app \
|
|
--host 0.0.0.0 \
|
|
--port 8300 \
|
|
--reload \
|
|
--env-file .env
|
|
```
|
|
|
|
Teste a saúde pública:
|
|
|
|
```bash
|
|
curl http://localhost:8300/health
|
|
```
|
|
|
|
Teste um endpoint protegido sem credencial:
|
|
|
|
```bash
|
|
curl -i http://localhost:8300/v1/tools
|
|
```
|
|
|
|
Esperado:
|
|
|
|
```text
|
|
HTTP/1.1 401 Unauthorized
|
|
```
|
|
|
|
Teste com Basic Auth:
|
|
|
|
```bash
|
|
curl -i \
|
|
-u 'agent-backend-test:BackendMcp-Test-2026!' \
|
|
http://localhost:8300/v1/tools
|
|
```
|
|
|
|
Esperado:
|
|
|
|
```text
|
|
HTTP/1.1 200 OK
|
|
```
|
|
|
|
---
|
|
|
|
## Terminal 3 — Agent Backend
|
|
|
|
```bash
|
|
cd Tuning-Performance/Authentication/agent_template_backend_authentication
|
|
source ../../../.venv/bin/activate
|
|
```
|
|
|
|
Suba:
|
|
|
|
```bash
|
|
uvicorn app.main:app \
|
|
--host 0.0.0.0 \
|
|
--port 8000 \
|
|
--reload \
|
|
--env-file .env
|
|
```
|
|
|
|
Teste saúde:
|
|
|
|
```bash
|
|
curl http://localhost:8000/health
|
|
```
|
|
|
|
Teste endpoint protegido sem credencial:
|
|
|
|
```bash
|
|
curl -i http://localhost:8000/agents
|
|
```
|
|
|
|
Esperado:
|
|
|
|
```text
|
|
HTTP/1.1 401 Unauthorized
|
|
```
|
|
|
|
Teste com a credencial usada pelo Agent Gateway:
|
|
|
|
```bash
|
|
curl -i \
|
|
-u 'agent-gateway-test:GatewayBackend-Test-2026!' \
|
|
http://localhost:8000/agents
|
|
```
|
|
|
|
Esperado:
|
|
|
|
```text
|
|
HTTP/1.1 200 OK
|
|
```
|
|
|
|
Teste mensagem diretamente:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8000/gateway/message \
|
|
-u 'agent-gateway-test:GatewayBackend-Test-2026!' \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{
|
|
"channel": "web",
|
|
"agent_id": "telecom_contas",
|
|
"tenant_id": "default",
|
|
"payload": {
|
|
"text": "Quero consultar minha fatura",
|
|
"session_id": "teste-backend-001",
|
|
"user_id": "user-001",
|
|
"customer_id": "12345",
|
|
"message_id": "msg-001"
|
|
}
|
|
}'
|
|
```
|
|
|
|
---
|
|
|
|
## Terminal 4 — Agent Gateway
|
|
|
|
```bash
|
|
cd apps/agent_gateway
|
|
source ../../.venv/bin/activate
|
|
```
|
|
|
|
Suba:
|
|
|
|
```bash
|
|
uvicorn app.main:app \
|
|
--host 0.0.0.0 \
|
|
--port 8010 \
|
|
--reload \
|
|
--env-file .env
|
|
```
|
|
|
|
Teste saúde:
|
|
|
|
```bash
|
|
curl http://localhost:8010/health
|
|
```
|
|
|
|
Teste endpoint protegido sem credencial:
|
|
|
|
```bash
|
|
curl -i http://localhost:8010/backends
|
|
```
|
|
|
|
Esperado:
|
|
|
|
```text
|
|
HTTP/1.1 401 Unauthorized
|
|
```
|
|
|
|
Teste com a credencial externa:
|
|
|
|
```bash
|
|
curl -i \
|
|
-u 'tia-test:TiaGateway-Test-2026!' \
|
|
http://localhost:8010/backends
|
|
```
|
|
|
|
Esperado:
|
|
|
|
```text
|
|
HTTP/1.1 200 OK
|
|
```
|
|
|
|
---
|
|
|
|
# 9. Validar o circuito completo
|
|
|
|
Force o backend `contas` para evitar que o roteador selecione um backend não iniciado:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8010/gateway/message \
|
|
-u 'tia-test:TiaGateway-Test-2026!' \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{
|
|
"channel": "web",
|
|
"backend_id": "contas",
|
|
"tenant_id": "default",
|
|
"agent_id": "telecom_contas",
|
|
"session_id": "circuito-basic-001",
|
|
"payload": {
|
|
"text": "Quero consultar minha fatura",
|
|
"session_id": "circuito-basic-001",
|
|
"user_id": "user-001",
|
|
"customer_id": "12345",
|
|
"message_id": "msg-circuito-001"
|
|
}
|
|
}'
|
|
```
|
|
|
|
O circuito esperado é:
|
|
|
|
```text
|
|
curl
|
|
│ Basic tia-test
|
|
▼
|
|
Agent Gateway :8010
|
|
│ Basic agent-gateway-test
|
|
▼
|
|
Agent Backend :8000
|
|
│ Basic agent-backend-test
|
|
▼
|
|
MCP Gateway :8300
|
|
▼
|
|
MCP Server :8100 ou :8200
|
|
```
|
|
|
|
---
|
|
|
|
# 10. Como comprovar cada autenticação
|
|
|
|
Faça testes negativos em cada trecho.
|
|
|
|
## Secret externo incorreto
|
|
|
|
```bash
|
|
curl -i \
|
|
-u 'tia-test:senha-errada' \
|
|
http://localhost:8010/backends
|
|
```
|
|
|
|
Resultado esperado:
|
|
|
|
```text
|
|
401 Unauthorized
|
|
```
|
|
|
|
## Secret do gateway para backend incorreto
|
|
|
|
Altere temporariamente no `apps/agent_gateway/.env`:
|
|
|
|
```env
|
|
BACKEND_AUTH_SECRET=senha-errada
|
|
```
|
|
|
|
Reinicie o Agent Gateway e envie uma mensagem.
|
|
|
|
O gateway deverá retornar erro de backend, normalmente:
|
|
|
|
```text
|
|
502 Bad Gateway
|
|
```
|
|
|
|
O erro interno será originado por um:
|
|
|
|
```text
|
|
401 Unauthorized
|
|
```
|
|
|
|
do Agent Backend.
|
|
|
|
## Secret do backend para MCP incorreto
|
|
|
|
Altere temporariamente:
|
|
|
|
```env
|
|
MCP_GATEWAY_BASIC_SECRET=senha-errada
|
|
```
|
|
|
|
Reinicie o backend e execute uma frase que acione uma ferramenta MCP.
|
|
|
|
O backend deverá registrar falha na chamada ao MCP Gateway com:
|
|
|
|
```text
|
|
401 Unauthorized
|
|
```
|
|
|
|
---
|
|
|
|
# 11. Verificação rápida de portas
|
|
|
|
No Linux ou WSL:
|
|
|
|
```bash
|
|
ss -lntp | grep -E ':8000|:8010|:8100|:8200|:8300'
|
|
```
|
|
|
|
No Windows PowerShell:
|
|
|
|
```powershell
|
|
Get-NetTCPConnection -State Listen |
|
|
Where-Object LocalPort -in 8000,8010,8100,8200,8300 |
|
|
Sort-Object LocalPort
|
|
```
|
|
|
|
Você deverá ver:
|
|
|
|
```text
|
|
8000 Agent Backend
|
|
8010 Agent Gateway
|
|
8100 Telecom MCP Server
|
|
8200 Retail MCP Server
|
|
8300 MCP Gateway
|
|
```
|
|
|
|
## Observação importante
|
|
|
|
O segredo original precisa existir no componente cliente:
|
|
|
|
```text
|
|
TIA ou curl:
|
|
TiaGateway-Test-2026!
|
|
|
|
Agent Gateway:
|
|
GatewayBackend-Test-2026!
|
|
|
|
Agent Backend:
|
|
BackendMcp-Test-2026!
|
|
```
|
|
|
|
Os componentes servidores armazenam apenas os hashes:
|
|
|
|
```text
|
|
Agent Gateway:
|
|
hash de TiaGateway-Test-2026!
|
|
|
|
Agent Backend:
|
|
hash de GatewayBackend-Test-2026!
|
|
|
|
MCP Gateway:
|
|
hash de BackendMcp-Test-2026!
|
|
```
|
|
|
|
Em produção, os segredos originais e hashes devem vir de Vault ou Kubernetes Secret, não de arquivos `.env`.
|