# Autenticación

Cada solicitud es autenticada con una **clave de API de espacio de trabajo**, enviado como una señal de portador:

```
Authorization: Bearer maetra_xxxxxxxxxxxxxxxxxxxx
```

Las llaves comienzan con `maetra_`. Una llave pertenece a un espacio de trabajo y lleva un conjunto fijo de **alcances**. La misma llave autentica [REST API](https://maetra.io/es/docs/getting-started/quickstart) y el [MCP server](https://maetra.io/es/docs/mcp-server/overview-and-connection).

### Crear una clave de API (en el panel de control)

1. Abra el panel de Maetra y vaya a **Ajustes → Claves de API**.
2. Haga clic **Crear clave de API**.
3. Rellene el diálogo:
   * **Nombre clave** - una etiqueta para reconocerla más tarde, por ejemplo. `Production FinanceAgent`.
   * **Alcances de acceso** - Elija **Acceso completo**, **Alcances personalizados** para elegir por módulo (Discover, Comply, Govern, Secure, Audit, Task Guard). Conceder las necesidades menos clave — ver [Scopes](#scopes) abajo.
   * **Restricciones de IP** *(opcional)* — uno o más IPs/CIDR rangos la clave puede ser usada, por ejemplo. `192.168.1.0/24`.
4. Haga clic **Crear**. La clave completa se muestra **una vez** - golpe **Copiar la clave**, guardarlo en un gestor secreto, entonces **He salvado mi llave.**.

> **Important**
> Maetra almacena sólo un hash de la llave y nunca puede mostrarlo de nuevo. Si una llave se pierde o se filtra, **revocarlo y crear uno nuevo** - No puedes recuperarlo.


### Scopes

Los tubos son revisados por solicitud. Una llamada regresa `403 Forbidden` si la clave es válida pero carece del alcance requerido.

| Ámbito | Subvenciones |
| -------------------------- | ------------------------------ |
| `govern:checkpoints:write` | Crear puntos de control |
| `govern:checkpoints:read` | Puntos de control de lectura / largos |
| `govern:policies:read` | Lista de políticas activas |
| `secure:scan:write` | Contenido de exploración |
| `secure:rules:read` | Lista de reglas de Secure |
| `secure:rules:write` | Crear y actualizar las reglas de Secure |
| `secure:incidents:read` | Número de incidentes |
| `discover:agents:read` | Lista de agentes registrados |
| `task_guard:tasks:write` | Iniciar, actualizar, pausar, reanudar, cancelar y completar las tareas de Task Guard |
| `task_guard:tasks:read` | Recuperar el contexto activo de la tarea de Task Guard |
| `task_guard:checks:write` | Controlar la alineación de la acción y explicar las relaciones de tarea |
| `task_guard:effects:write` | Informe y compare los efectos reales de la acción |
| `task_guard:confirmations:write` | Presentar eventos de usuario de host de confianza y confirmaciones de alcance |

#### Wildcards

Una llave puede tener alcances de comodín: `*` (todo), o un prefijo de módulo como `govern:*` / `secure:*` / `discover:*` / `task_guard:*`. El dashboard **Acceso completo** Subvenciones `*`; elegir un módulo completo bajo **Alcances personalizados** subvenciones de ese módulo `*`.

> **Note**
> `task_guard:confirmations:write` es necesario pero no suficiente para eventos de confianza y confirmaciones de alcance en línea. La clave de API también debe ser marcada como una creíble confirmación de Task Guard para el espacio de trabajo.


### Revisar la llave

Uso `GET /v1/ping` para confirmar una clave es válida y ver sus alcances:

#### cURL

```bash
curl "https://api.maetra.io/v1/ping" \
  -H "Authorization: Bearer $MAETRA_API_KEY"
```

#### JavaScript

```javascript
const res = await fetch("https://api.maetra.io/v1/ping", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MAETRA_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Maetra API ${res.status}`);
const data = await res.json();
console.log(data);
```

#### TypeScript

```typescript
const res = await fetch("https://api.maetra.io/v1/ping", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MAETRA_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Maetra API ${res.status}`);
const data = (await res.json());
```

#### Python

```python
import os, requests

res = requests.get(
    "https://api.maetra.io/v1/ping",
    headers={"Authorization": f"Bearer {os.environ['MAETRA_API_KEY']}"},
)
res.raise_for_status()
print(res.json())
```

#### Rust

```rust
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("MAETRA_API_KEY")?;
    let client = reqwest::Client::new();
    let res = client
        .get("https://api.maetra.io/v1/ping")
        .bearer_auth(&key)
        .send()
        .await?;
    let data: serde_json::Value = res.json().await?;
    println!("{data:#}");
    Ok(())
}
```

#### C++

```cpp
#include <curl/curl.h>
#include <cstdlib>
#include <string>

int main() {
    CURL* curl = curl_easy_init();
    std::string auth = "Authorization: Bearer " + std::string(std::getenv("MAETRA_API_KEY"));
    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, auth.c_str());
    curl_easy_setopt(curl, CURLOPT_URL, "https://api.maetra.io/v1/ping");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_perform(curl);   // response is written to stdout by default
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return 0;
}
```

#### Java

```java
import java.net.URI;
import java.net.http.*;

var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.maetra.io/v1/ping"))
    .header("Authorization", "Bearer " + System.getenv("MAETRA_API_KEY"))
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```


```json
{ "ok": true, "workspace_id": "ws_3Nf9k2", "scopes": ["govern:checkpoints:write"] }
```

### Rechazar una llave

Rechazar una llave de **Ajustes → Claves de API** (el menú de acciones de la fila). La revocación es inmediata - nuevas solicitudes de devolución `401 Unauthorized`. Revocar una clave nunca afecta a los demás.

Véase [Límites de velocidad de errores](https://maetra.io/es/docs/getting-started/errors-and-rate-limits) para el formato completo de error.