Integración SII · cis-sii-gateway¶
Última revisión: 2026-05-09 · Owner:
cis-sii-gateway teamFuentes canónicas:/srv/projects/cds/cis/cis-sii-gateway/CLAUDE.md,AGENT-CONTEXT.md,CERTIFICATION-STATUS.md.
Qué es¶
cis-sii-gateway es el gateway interno CIS que media entre los servicios del ecosistema (cis-admin, cis-claudia, cis-mailer, etc.) y el Servicio de Impuestos Internos (SII) de Chile. Es el único servicio del ecosistema que habla SII; nadie más debe abrir conexiones directas a maullin.sii.cl / palena.sii.cl / www2.sii.cl.
- Puerto:
127.0.0.1:8270(loopback) - Systemd unit:
cis-sii-gateway.service - Stack: FastAPI + Playwright (scrape) + httpx (api) + slowapi (rate-limit) + Prometheus
- Path:
/srv/projects/cds/cis/cis-sii-gateway(symlink/srv/projects/cis/cis-sii-gateway)
Multi-tenant desde día uno: cada operación lleva un tenant (RUT tributario). El token SII se cachea en memoria por (tenant, sii_env) con TTL ≈ 18 minutos.
Reglas duras¶
- Nunca tocar la PFX directamente. Toda operación criptográfica va por HTTP a
cis-signen127.0.0.1:8250. SII_ENV=certpor default (maullin · ambiente certificación). Producción (palena) no se habilita hasta que CIS esté certificado como emisor por el SII.- Scrape de portal usa Playwright con sesión logueada vía cert centralizado, no PFX local. Esa vía es solo para
api_engine. - Rate limit:
slowapiaplica 20 req/min en emisión y 60 req/min en recepción. Scraping: máximo 1×/día por RUT (riesgo ban IP). - No commitear fixtures con datos reales del SII. Usar mocks (ver
tests/conftest.py).
Quién lo consume¶
| Consumidor | Uso típico |
|---|---|
cis-admin (módulo tributario, ADR-032) |
Carpeta tributaria, situación SII, declaraciones F29/F22, libros IVA, emisión DTE. |
cis-claudia |
Queries tributarias del asistente (validación RUT, lookups de contribuyente, estado de DTE). |
cis-mailer |
Triggering de notificaciones cuando llega un evento SII (vía notif/inbox.py → cis-inbox). |
Servicios no listados no deben llamar al gateway directamente. Si necesitan datos tributarios, pasan por cis-admin.
Endpoints expuestos¶
Todos en 127.0.0.1:8270. Auth interna: header X-Internal-Key con shared-key (ADR-012 — service-to-service auth).
Implementados¶
| Método + path | Descripción | Notas |
|---|---|---|
GET /health · GET /healthz |
Health check. | Público (no requiere auth interna). |
POST /sii/auth/token |
Seed → sign (vía cis-sign) → token. | Cache 18 min por (tenant, env). |
DELETE /sii/auth/token |
Invalida cache de token. | Para forzar re-auth. |
POST /sii/auth/import-session |
Importa cookies de sesión SII (browser). | Para scrape de RUTs ajenos donde el cert holder es mandatario. |
GET /sii/auth/import-session/status |
Estado de la sesión importada. | |
DELETE /sii/auth/import-session/{representado_rut} |
Limpia sesión por representado. | |
GET /sii/contribuyente/estado |
Estado tributario (vigente, exento, etc.). | Cache 24h. |
GET /sii/contribuyente/datos |
Datos canónicos (razón social, dirección, giros). | Source of truth para validación RUT (regla anti-alucinación). Cache 24h. |
GET /sii/contribuyente/datos-rut/{rut} |
Igual al anterior pero con RUT en path. | Útil para webhooks. |
GET /sii/contribuyente/giros |
Lista de giros activos del contribuyente. | Cache 24h. |
GET /sii/contribuyente/representantes |
Representantes legales. | Cache 24h. |
POST /sii/contribuyente/cache/clear |
Invalida cache contribuyente. | 204. |
POST /sii/scrape/carpeta |
Carpeta tributaria (PDF). | Playwright + REST cte-api. Rate limit 1×/día por RUT. |
POST /sii/scrape/carpeta/json |
Carpeta tributaria estructurada (CarpetaTributaria schema). |
Wrapper sobre los endpoints REST de la SPA Vue del SII. |
POST /sii/caf/upload |
Sube archivo CAF (folios timbrados). | Body: multipart con XML CAF. |
GET /sii/caf/status |
Estado de folios disponibles por tipo DTE. | |
POST /sii/caf/resync |
Re-sincroniza folios contra el SII. | |
POST /sii/dte/emitir |
Emite DTE (factura/NC/ND/exenta). | Requiere CAF activo. Rate limit 20/min. |
GET /sii/dte/estado |
Estado de envío DTE al SII. | Por trackid. |
GET /sii/dte/get/{emision_id} |
Detalle de DTE emitido (XML + tracking). | |
GET /sii/dte/pending |
DTEs pendientes (no enviados o con error). | |
GET /sii/dte/{emision_id}/pdf |
PDF timbrado del DTE. | Re-genera si no existe. |
POST /sii/libros/generar |
Genera libro IVA (compras/ventas) del periodo. | Devuelve LibroResponse. |
POST /sii/libros/enviar/{libro_id} |
Envía libro al SII. | |
GET /sii/libros · GET /sii/libros/{libro_id} |
Listado / detalle de libros. | |
POST /sii/recepcion/dte |
Recibe DTE entrante (proveedor → CIS). | Rate limit 60/min. |
GET /sii/recepcion |
Listado de DTEs recibidos. | |
GET /sii/registro/empresa/{rut} |
Registro de empresas SII (Empresa schema). | |
GET /sii/registro/empresa/{rut}/historial |
Modificaciones registradas. | |
POST /sii/registro/cache/clear |
204. | |
GET /sii/notificaciones · /{notif_id} |
Notificaciones SII (buzón electrónico). | |
GET /sii/documentos · /{doc_id}/pdf |
Documentos del SII (resoluciones, certificados). | |
POST /sii/notificaciones/cache/clear |
204. | |
GET /sii/certificacion/sets |
Sets de certificación disponibles. | Ver CERTIFICATION-STATUS.md. |
POST /sii/certificacion/run |
Corre un set de certificación. | Devuelve summary por caso. |
POST /banco/refresh · GET /banco/health |
(Pivot reciente, ver gateway team). | Refresh de movimientos bancarios cacheados. |
GET /metrics |
Prometheus metrics. | 9 contadores/histogramas. |
Pendientes / TBD¶
Estos endpoints aparecen en el plan pero requieren input humano (folios, certificación) antes de poder operar. Si tu servicio los va a consumir, verificá con cis-sii-gateway team que el flujo end-to-end esté disponible.
/sii/dte/emitirpara producción (palena) — bloqueado por certificación SII pendiente./sii/boleta/emitir(REST boleta electrónica) — implementación parcial; requiere número de atención SII por RUT emisor./sii/rcv/libro(libro de compras/ventas vs. RCV oficial) — implementado el envío básico (/sii/libros); reconciliación con RCV pendiente./sii/cafupload + ciclo completo de timbraje — endpoints existen (ver tabla); falta runbook humano para subir folios timbrados nuevos.- Audit log FES por cada operación (vía
cis-sign /sign/cms) — pendiente. - Métricas Prometheus extra (latencia por endpoint SII upstream) — parcial.
- Multi-tenant production-ready — hoy soporta tenant en cada request, pero el cache es in-memory per-process y no escala más allá de un solo nodo.
Auth interna (ADR-012)¶
Service-to-service va con shared-key header (no trusted-IP):
POST /sii/auth/token HTTP/1.1
Host: 127.0.0.1:8270
X-Internal-Key: <shared-key del caller>
Content-Type: application/json
{"tenant": "78384591-1"}
Cada caller (cis-admin, cis-claudia, cis-mailer) tiene su propia key registrada en vault del gateway:
vault get cis-sii-gateway INTERNAL_KEY_CIS_ADMIN
vault get cis-sii-gateway INTERNAL_KEY_CIS_CLAUDIA
vault get cis-sii-gateway INTERNAL_KEY_CIS_MAILER
El gateway compara contra una lista declarada en app/config.py. Si una key falta o no matchea → 401 unauthorized.
Auth de usuarios humanos (OIDC vía cis-auth) está fuera del scope del gateway: el gateway solo confía en sus consumidores internos, que son quienes ya autenticaron al usuario aguas arriba.
Datos canónicos (regla anti-alucinación)¶
El RUT empresa debe validarse contra GET /sii/contribuyente/datos antes de:
- Crear una nueva empresa en cualquier base CIS (cis_admin.empresas, cis_claudia.assistants_empresas, etc.).
- Emitir cualquier DTE / boleta.
- Mostrar la razón social en cualquier UI.
El gateway responde con la razón social oficial SII y normaliza el RUT (con DV, sin puntos). Esto es la única source of truth: nada de tomar la razón social de un campo libre del usuario, ni de un OCR, ni de Claudia.
Cómo agregar un endpoint nuevo¶
Patrón canónico (basado en app/routes/sii_contribuyente.py):
- Router en
app/routes/<area>.pyconprefix="/sii/<area>". - Schema Pydantic en
app/schemas/<area>.py(request + response). No exponer modelos SQLAlchemy. - Servicio en
app/services/<area>_service.pyque: - Recibe
tenanty obtiene token víaauth.get_token(tenant, env). - Llama al SII vía
sii_client(httpx) oscrape_engine(Playwright) según corresponda. - Escapa cookies y headers SII antes de loggearlos (PII, session leakage).
- Cache opcional: si la respuesta del SII es idempotente para una ventana de tiempo, cachear con
cachetools.TTLCache(24h estado contribuyente, 18min token). - Rate limit: agregar decorador
@limiter.limit("20/minute")si toca al SII upstream. - Test en
tests/test_<area>.pycon mocks desii_clientyscrape_engine. Integración real entests/integration/conSII_INTEGRATION=1. - Audit FES (cuando esté listo): cada operación critical/high pasa por
cis-sign /sign/cmspara receipt firmado (ADR-008). - Documentar en este file + en
/srv/projects/cis/CONTRACTS.md(provider=cis-sii-gateway).
Pendientes humanos (HUMAN)¶
Estos no son tareas de Claude — requieren acción del owner técnico/legal:
- Cert FEA producción: comprar y registrar el cert PFX para producción
palena. Hoy operamos con cert de Martín en cert/maullin. - Folios CAF: solicitar timbraje al SII por RUT emisor (CIS, CDS) y subir CAFs vía
POST /sii/caf/upload. VerCERTIFICATION-STATUS.md— bloqueador actual de la certificación. - Número de atención SII para boleta electrónica por RUT emisor. Trámite humano en oficina virtual SII.
- Multi-tenant: hoy el gateway atiende todos los tenants en un solo proceso; si crece a >50 tenants activos, evaluar split por shard (
cis-sii-gateway-cis,cis-sii-gateway-cds, etc.) o token cache distribuido (Redis).
Referencias¶
- Runbook operacional →
runbooks/cis-sii-gateway.md - ADR-012 (service-to-service auth) →
adrs/ADR-012-service-to-service-auth.md - ADR-032 (cis-sii-monitor → módulo tributario en cis-admin) →
adrs/ADR-032-cis-sii-monitor-pivot.md - Estado certificación →
/srv/projects/cds/cis/cis-sii-gateway/CERTIFICATION-STATUS.md - Contratos vivos →
/srv/projects/cis/CONTRACTS.md(filas Provider=cis-sii-gateway)