# Autenticación de agentes — Inmovilla

Cómo un agente o integración obtiene credenciales y llama a la API de
Inmovilla (REST y MCP). Dos métodos:

1. **OAuth 2.1** — para clientes MCP (Claude Desktop, ChatGPT y cualquier
   cliente compatible). Registro dinámico de cliente, PKCE S256 y refresh
   tokens rotativos. Un editor del panel inicia sesión y autoriza el conector.
2. **Bearer API token estático** (`imv_…`) — creado por un administrador en
   el panel para integraciones servidor-a-servidor.

Ambos producen el mismo tipo de credencial: un token `imv_…` con permisos
`resource:action`.

## Discover

- Metadata del authorization server (RFC 8414): `https://www.inmovilla.com/.well-known/oauth-authorization-server`
- Metadata del recurso protegido (RFC 9728): `https://www.inmovilla.com/.well-known/oauth-protected-resource/api/v1/mcp` (también en la raíz `/.well-known/oauth-protected-resource`)
- Especificación de la API: `https://www.inmovilla.com/openapi.json`
- Servidor MCP: `https://www.inmovilla.com/api/v1/mcp` (server card en `https://www.inmovilla.com/.well-known/mcp/server-card.json`)
- Un `401` del MCP incluye `WWW-Authenticate: Bearer resource_metadata="…"` apuntando a la metadata anterior.

## Pick a method

- `oauth2` (authorization_code + PKCE, `refresh_token`): recomendado para
  asistentes de escritorio y cualquier cliente que actúe en nombre de una
  persona. Scopes = permisos `resource:action`; sin `scope` se concede todo
  lo que el editor puede delegar.
- `service_auth` con Bearer token estático: integraciones sin humano en el
  bucle.

## Register

**OAuth:** `POST https://www.inmovilla.com/api/v1/oauth/register` (RFC 7591) con
`redirect_uris` (https, o http en localhost) y opcionalmente `client_name`,
`token_endpoint_auth_method` (`none` por defecto). Solo se aceptan hosts de
redirección conocidos (claude.ai, claude.com, chatgpt.com, openai.com,
localhost); otros hosts requieren configuración del servidor.

**Token estático:** lo crea un administrador en `https://www.inmovilla.com/admin/api`.
Si representas a un agente sin acceso humano, solicita acceso vía
`https://www.inmovilla.com/contact`.

## Claim

**OAuth:** redirige al usuario a
`https://www.inmovilla.com/admin/oauth/authorize?response_type=code&client_id=…&redirect_uri=…&code_challenge=…&code_challenge_method=S256&state=…`.
El editor inicia sesión (Microsoft SSO o contraseña) y aprueba la pantalla de
consentimiento; vuelves a `redirect_uri` con `code` y `state`.

**Token estático:** al crearlo se muestra **una sola vez** en claro. Solo se
almacena su hash.

## Exchange

`POST https://www.inmovilla.com/api/v1/oauth/token` (`application/x-www-form-urlencoded`)
con `grant_type=authorization_code`, `code`, `redirect_uri`, `client_id`
y `code_verifier`. Respuesta: `access_token` (`imv_…`, 7 días),
`refresh_token` (90 días, rotativo), `expires_in`, `scope`.
Renueva con `grant_type=refresh_token`; cada renovación invalida el
refresh token anterior y retira el access token antiguo.

## Use the access_token

```bash
curl -H "Authorization: Bearer imv_TU_TOKEN" \
  "https://www.inmovilla.com/api/v1/docs?limit=5"
```

Permisos con formato `resource:action` (`docs:read`, `blog:write`,
comodines `*:read`, `*:*`). El MCP filtra `tools/list` según los
permisos del token.

## Errors

Errores REST en JSON: `{ "error": { "code", "message", "timestamp" } }`.
Errores OAuth según RFC 6749: `{ "error", "error_description" }`.

- `401 UNAUTHORIZED` — token ausente, inválido, revocado o expirado. La
  respuesta incluye `WWW-Authenticate: Bearer resource_metadata="…"`.
- `403 FORBIDDEN` — token válido sin el permiso requerido; la respuesta
  indica el permiso que falta. No reintentes: pide un token con más scope.
- `invalid_grant` — código usado/caducado, PKCE incorrecto o refresh token
  rotado. Reinicia el flujo de autorización.
- `429` — rate limit; respeta `Retry-After`.

## Revocation

- Self-service: `POST https://www.inmovilla.com/api/v1/oauth/revoke` (RFC 7009) con
  `token=` (access o refresh).
- Un administrador puede desactivar o borrar cualquier token (manual u OAuth)
  en `https://www.inmovilla.com/admin/api` con efecto inmediato.
