> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basaltic.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Permisos de DNS

> El servicio DNS comprueba cada acción de IAM, qué llamada la necesita y los recursos a los que una directiva puede aplicarla.

Cada punto final DNS comprueba una acción de IAM antes de hacer cualquier cosa. Esta es la lista completa, no hay otros, y ningún punto final se salta la comprobación.

<Info>
  La referencia de la API muestra la acción en la página propia de cada punto final, por lo que no tiene que volver aquí para buscar una. Ambos provienen del mismo lugar: la llamada de autorización en el servicio, leída en el momento de la compilación.
</Info>

<a id="the-actions" />

## Las acciones

Dos de estos no son adivinables desde el punto final, y son la razón por la que existe esta tabla en lugar de una regla de nombres:

* **Exportar un archivo de zona** necesita `dns:ListRecords`, no una acción de exportación propia. La exportación es una lectura de todos los registros de la zona, por lo que se bloquea como uno.
* **Leer el resultado de la importación de registros** necesita `dns:GetZone`. Describe algo que le sucedió a la zona, no un registro. **Descartar** necesita `dns:UpdateZone` — cambia lo que la zona registra sobre sí misma, y no hay acción separada para una pieza de metadatos de zona.

| Acción y aventura | Llamada |
| - | - |
| `dns:ListZones` | `GET /v1/zones` |
| `dns:CreateZone` | `POST /v1/zones` |
| `dns:GetZone` | `GET /v1/zones/{zone_id}` |
| `dns:GetZone` | `GET /v1/zones/{zone_id}/record-import` |
| `dns:UpdateZone` | `PATCH /v1/zones/{zone_id}` |
| `dns:UpdateZone` | `DELETE /v1/zones/{zone_id}/record-import` |
| `dns:DeleteZone` | `DELETE /v1/zones/{zone_id}` |
| `dns:VerifyZoneOwnership` | `POST /v1/zones/{zone_id}/verify-ownership` |
| `dns:ImportZoneFile` | `POST /v1/zones/{zone_id}/import` |
| `dns:ListRecords` | `GET /v1/zones/{zone_id}/records` |
| `dns:ListRecords` | `GET /v1/zones/{zone_id}/export` |
| `dns:CreateRecord` | `POST /v1/zones/{zone_id}/records` |
| `dns:GetRecord` | `GET /v1/zones/{zone_id}/records/{record_id}` |
| `dns:UpdateRecord` | `PATCH /v1/zones/{zone_id}/records/{record_id}` |
| `dns:DeleteRecord` | `DELETE /v1/zones/{zone_id}/records/{record_id}` |
| `dns:ListVPCAssociations` | `GET /v1/zones/{zone_id}/vpc-associations` |
| `dns:AssociateVPC` | `POST /v1/zones/{zone_id}/vpc-associations` |
| `dns:DissociateVPC` | `DELETE /v1/zones/{zone_id}/vpc-associations/{vpc_id}` |

<a id="resources" />

## Recursos

Las acciones DNS se comprueban con una de las dos formas de recursos:

```
crn:dns::<account>:zone/<zone-name>
crn:dns::<account>:zone/<zone-name>/record/<record-id>
```

La ranura de región está vacía porque DNS es global: hay un extremo y un conjunto de zonas, no uno por región.

Un registro se identifica por su **UUID**, no por su nombre y tipo. Los nombres de registros contienen legítimamente `*`, que es un comodín en un CRN también, por lo que una política escrita contra `record/*.example.com` coincidiría mucho más que el nombre que parece.

<a id="writing-a-policy" />

## Escribir una póliza

Solo lectura en todas las zonas de la cuenta:

```json theme={null}
{
  "version": "2024-01-01",
  "statements": [
    {
      "sid": "ReadDNS",
      "effect": "allow",
      "actions": [
        "dns:ListZones",
        "dns:GetZone",
        "dns:ListRecords",
        "dns:GetRecord"
      ],
      "resources": ["crn:dns::my-account:zone/*"]
    }
  ]
}
```

Control total de una zona y nada más:

```json theme={null}
{
  "version": "2024-01-01",
  "statements": [
    {
      "sid": "OwnOneZone",
      "effect": "allow",
      "actions": ["dns:*"],
      "resources": [
        "crn:dns::my-account:zone/example.com",
        "crn:dns::my-account:zone/example.com/record/*"
      ]
    }
  ]
}
```

<Warning>
  **Se necesitan ambas líneas de recursos.** `zone/example.com` no cubre los registros debajo de él — el CRN de un registro es una ruta más larga, y una coincidencia de comodín se detiene en el recurso que nombra. Una política con solo la primera línea permite a alguien leer y eliminar la zona, pero no tocar un solo registro en ella.
</Warning>

`dns:ListZones` se comprueba en la cuenta en lugar de una zona con nombre, por lo que no puede ser ampliado a una zona. Si se concede, se concede la capacidad de ver que existen todas las zonas de la cuenta, aunque no de leer lo que contienen.

<a id="what-a-denial-looks-like" />

## Qué aspecto tiene una negación

Una comprobación fallida responde `403`:

```json theme={null}
{
  "error": {
    "code": "ACCESS_DENIED",
    "message": "You don't have permission to perform this action",
    "request_id": "..."
  }
}
```

**No le dice qué acción faltaba**, deliberadamente — el mensaje es el mismo para cada denegación, por lo que no se puede usar para mapear lo que una credencial puede y no puede alcanzar. Por eso existe la tabla de arriba: busca la llamada que hiciste, y la acción que necesita es la que se debe agregar.

<Note>
  Un `404` no es un `403` disfrazado. La propiedad y la autorización son controles separados: una zona que pertenece a otra cuenta responde `404` porque no es suya para ver, y una que usted posee pero carece de la acción para respuestas `403`. Si está recibiendo `404` en una zona que cree que es suya, compruebe la cuenta a la que pertenece la credencial antes de comprobar la política.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.