# Capacidades y tokens de API

La palabra *capacidad* se usa en Zaroz para dos cosas distintas. Están relacionadas pero no son lo mismo.

## Capacidades de servicio: lo que puede hacer un servicio

Cada instancia de servicio expone una lista de **capacidades** que su producto ofrece y que sus recursos soportan: `log_stream`, `metrics`, `files`, `source`, `deployments`, `environment`, `external_access`, `schedules`, `backups`, `custom_domain`, etcétera. La consola construye sus pestañas a partir de esa lista, y tú también puedes:

**curl**

```bash
curl -sS "$ZAROZ_API/service-instances/$SERVICE/capabilities" -H "$AUTH"
```

**TypeScript**

```ts
const { body: caps } = await call("GET", `/service-instances/${SERVICE}/capabilities`);
console.log(caps.map((c: any) => c.capability));   // e.g. ["log_stream", "metrics", "source", "deployments"]
```

**Python**

```python
_, caps = call("GET", f"/service-instances/{SERVICE}/capabilities")
print([c["capability"] for c in caps])   # e.g. ["log_stream", "metrics", "source", "deployments"]
```


Un producto sin `deployments` no tiene pestaña de despliegues y su ruta de despliegues responde 404. Así una sola API sirve a un servidor de Minecraft, una VPS y un Workload sin casos especiales.

## Tokens de API

Un token es una credencial para scripts. Lleva una lista de **permisos concedidos**, cada uno con un permiso y un alcance:

```json
{"capability": "services.deploy",
 "scope": {"kind": "resource", "resource_type": "service_instance", "resource_id": "<uuid>"}}
```

| `kind` del alcance | Llega a |
|---|---|
| `global` | el permiso sobre todo lo que alcanza quien creó el token |
| `resource_type` | todos los recursos de un tipo, por ejemplo todas las instancias de servicio |
| `resource` | exactamente un recurso |
| `resource_tree` | un recurso y los que descienden de él |

Reglas que mantienen seguros los tokens:

- Un token nunca puede hacer más que lo que puede hacer ahora mismo la persona que lo creó: los permisos se comprueban de nuevo en cada petición.
- Solo puedes conceder lo que tienes (`GET /me/api-token-capabilities` lo lista). Los permisos solo para personal no pueden ir en un token de organización, y en uno personal requieren una sesión elevada de personal.
- Una lista vacía crea un token que no puede hacer nada. La ausencia deniega.
- El secreto se muestra una vez y solo se guarda su huella. Revoca con `DELETE /me/api-tokens/{token_id}` o, en una organización, `DELETE /organizations/{id}/api-tokens/{token_id}`.
- Los tokens de organización son `membership_tied` por defecto (se revocan cuando quien los creó se va) y pueden ser `organization_owned` para sobrevivirle.

Los permisos que actúan sobre un servicio llevan el nombre del servicio:

| Permiso | Permite |
|---|---|
| `services.read` | toda lectura no secreta de un servicio |
| `services.manage` | cambiar el servicio: entorno, copias, archivos, cortafuegos, y además todo lo que hace `services.deploy` |
| `services.deploy` | despliegues desde CI: cambiar el source y crear despliegues, nada más |
| `services.power` | iniciar, detener, reiniciar |
| `services.console` | flujo de logs, consola de comandos, SSH |
| `services.files.read` | explorar y descargar archivos |
| `services.external_access.manage` | abrir y cerrar puertos públicos |
| `services.schedules.manage` | tareas programadas |
| `services.databases.read` | explorar bases de datos conectadas |

Para el caso concreto de CI, mira [Despliega desde CI](/es/guides/ci/overview). El código que corre **dentro** de un Workload no debería usar un token tuyo: usa un [principal de servicio](/es/guides/units-api/principals).
