# Authentication Chain

Muchas acciones en el protocolo Decentraland requieren o se benefician de la autorización con una firma de la cuenta de Ethereum del usuario. Por ejemplo:

1. Subir una nueva versión de cualquier [Entity](https://github.com/decentraland/docs/blob/main/content/entities.md) que poseen (como su perfil).
2. Autenticarse ante servicios de terceros.
3. Autorizar delegados para actuar en su nombre.

Para realizar estas acciones, los usuarios y delegados deben firmar cargas útiles que describan su intención y producir un *auth chain*.

## Introducción

Las cadenas de autenticación encapsulan una serie de pasos de verificación, donde cada paso depende de la verificación exitosa del anterior. Todos los pasos deben considerarse válidos por el verificador para que se realice cualquier acción restringida.

Cada cadena comienza identificando al usuario y termina con una carga útil firmada que representa la acción solicitada. La cadena más pequeña contiene así dos elementos, que indican:

```md
1. La autoridad es la cuenta de Ethereum <user-address>
2. La carga útil es <payload>, autorizada por <user-signature>
```

Esta cadena básica puede evaluarse verificando que la clave pública de la firma corresponde con la dirección. En este caso, es equivalente a una firma simple.

Cuando los usuarios autorizan delegados para actuar en su nombre, aparecen pasos intermedios en la cadena. Por ejemplo, una cadena con una sola delegación indicaría:

```md
1. La autoridad es la cuenta de Ethereum <user-address>
2. El delegado es <delegate-address>, autorizado por <user-signature> hasta <date>
3. La carga útil es <payload>, autorizada por <delegate-signature>
```

Las cadenas son más largas cuando los delegados autorizan a sus propios delegados. En otras palabras, la autorización es transitiva.

{% hint style="info" %}
Puedes pensar en las cadenas de autenticación como análogas a las cadenas de certificados TLS utilizadas en HTTPS, con el usuario como equivalente de la autoridad raíz.
{% endhint %}

Esta cadena de un solo delegado es la forma de autorización más común usada en Decentraland, ya que los usuarios autorizan una clave para su World Explorer para evitar tener que firmar cada acción individual con su cuenta de Ethereum.

### Construcción de una Cadena <a href="#constructing" id="constructing"></a>

Cada paso en la cadena de autenticación contiene tres piezas de información: un `type`, un `payload` y una correspondiente `firma`.

| Campo     | Valor                                                                   |
| --------- | ----------------------------------------------------------------------- |
| `type`    | El nombre de un tipo ([ver más abajo](#types)).                         |
| `payload` | Una cadena dependiente del tipo.                                        |
| `firma`   | La firma Ethereum codificada en hex del `payload`, comenzando con `0x`. |

{% hint style="info" %}
Dado que la serialización más común de una cadena de autenticación es un arreglo JSON, los ejemplos abajo se presentan en esa forma. Ver [Transmisión de una Cadena](#transmitting) para más detalles.
{% endhint %}

### Primer Paso: Identificación

El primer paso, que identifica la autoridad original (es decir, el usuario), debe cumplir estas condiciones:

1. El `type` es [`SIGNER`](#SIGNER)
2. El `payload` es la cuenta de Ethereum codificada.
3. El `firma` está vacío.

Por ejemplo:

```json
// Primer paso en cualquier cadena de autenticación:
{
  "type": "SIGNER",
  "payload": "0xdB055877e6c13b6A6B25aBcAA29B393777dD0a73",
  "signature": ""
}
```

El segundo paso debe llevar una `firma` de esta cuenta para su `payload`.

### Pasos Intermedios: Delegación

Cuando los delegados actúan en nombre del usuario, se agrega un elemento en el medio de la cadena por cada uno de ellos. Las condiciones para estos pasos son:

1. El tipo es [`ECDSA_EPHEMERAL`](#ECDSA_EPHEMERAL)
2. El `payload` es un texto especialmente elaborado (ver más abajo).

El `payload` está diseñado para ser fácil de leer y fácil de analizar, ya que tanto humanos (cuando usan la interfaz de su wallet) como programas (cuando lo crean y validan) deben trabajar con él. Contiene exactamente 3 líneas de texto plano sensible a mayúsculas:

```md
<purpose>
Dirección efímera: <delegate-address>
Expiración: <date>
```

Por ejemplo, esta es una carga útil típica usada por World Explorers durante el inicio de sesión, cuando generan su clave delegada temporal para que el usuario la apruebe:

```
Decentraland Login
Dirección efímera: 0xBB9aDF0183b1742196A4Aa55622D5838f4f483a7
Expiración: 2023-02-25T13:00:19.730Z
```

Nótese que:

1. El `Dirección efímera` no necesita ser una cuenta de Ethereum real con fondos en la blockchain. El campo puede representar únicamente una clave pública temporal.
2. El `Expiración` es una fecha y hora serializada en [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) formato. No necesita ser UTC.
3. La clave delegada debe renovarse periódicamente con una firma nueva del usuario, debido a esta fecha de expiración.

{% hint style="info" %}
Es práctica estándar (y muy recomendable) generar una nueva clave en cada renovación (de ahí el nombre `ECDSA_EPHEMERAL`).
{% endhint %}

Un ejemplo de paso de delegación (valores abreviados para mayor claridad):

```json
{
  "type": "ECDSA_EPHEMERAL",
  "payload": "Decentraland Login\nEphemeral address: 0xBBa7...\nExpiration: 2021-01-25T...",
  "signature": "0x1370a4120a7cb0d2f6e4a5..."
}
```

El siguiente paso, ya sea otra delegación o la autorización final, lleva una firma de la clave de este delegado.

### Último Paso: Autorización

Después de que el `SIGNER` haya sido especificado y todas las `ECDSA_EPHEMERAL` claves delegadas fueron validadas verificando la cadena de firmas intermedias, el paso final es la acción real que necesita ser autorizada.

El `payload` depende del `type` del paso. Por ejemplo, si un usuario está subiendo un nuevo perfil (o cualquier entity que posea) a un servidor de contenido, el último elemento tendrá esta forma:

```json
{
  // El tipo indica que `payload` es un ID de entity (detalles en la sección Content):
  "type": "ECDSA_SIGNED_ENTITY",

  // La carga útil es la cadena ID sin procesar:
  "payload": "bafkreicfbg7ybpuoslkcf6x2vfnvzl5vwgqtb2pnheqiut2i4sgpblicqi",

  // La firma es producida por la cuenta en el paso anterior (usuario o delegado):
  "signature": "0x7e71dbbab..."
}
```

Si esta última firma también es válida, la acción puede continuar.

### Transmisión de una Cadena <a href="#transmitting" id="transmitting"></a>

Como se mencionó arriba, la serialización más común de una cadena de autenticación es un arreglo JSON. Este es el enfoque recomendado.

Sin embargo, el protocolo no impone esto. Los desarrolladores pueden usar una estrategia de serialización alternativa si es más conveniente para un caso de uso particular, como YAML, archivos CSV, formatos binarios optimizados o cadenas simples con campos delimitados.

Un ejemplo de serialización alternativa dentro del propio protocolo se puede encontrar en el [`SignedFetch`](https://github.com/decentraland/docs/blob/main/runtime/modules/signed_fetch.md) módulo, que usa una secuencia de cabeceras HTTP en lugar de un arreglo JSON.

### Elegir una Fecha de Expiración

Al seleccionar la duración válida para una clave delegada, hay una compensación: expiraciones más cortas aumentan la seguridad, pero expiraciones más largas mejoran la experiencia del usuario (ya que los delegados deben renovarse con interacción humana con menor frecuencia).

No existe una estrategia universal para decidir cuál debe ser la ventana de tiempo válida. Para referencia, el World Explorer de la Foundation solicita autorización para su clave delegada por un mes.

{% hint style="info" %}
Las claves efímeras nunca deben contener fondos ni poseer la capacidad de transferir activos digitales. Es mucho más seguro para los usuarios finales si la filtración de una clave efímera no puede resultar en pérdidas financieras.
{% endhint %}

## Formalización

A continuación hay una definición más formal y precisa de los procesos involucrados. Sigue estas instrucciones para manejar con éxito las cadenas de autenticación.

### Creación

Los clientes que crean una cadena de autenticación para el usuario siguen estos pasos:

1. Agregar el paso de identificación:
   1. Establecer el `type` a `SIGNER`.
   2. Establecer el `payload` a la dirección de Ethereum del usuario.
   3. Establecer el `firma` a una cadena vacía.
2. Agregar pasos de delegación:
   1. Generar o usar una clave privada de delegado existente (puede requerir interacción).
   2. Calcular la dirección Etherum del delegado derivada de la clave pública correspondiente.
   3. Establecer el `type` a `ECDSA_EPHEMERAL`.
   4. Establecer el `expiración` a una fecha en el futuro.
   5. Elegir un `propósito` para esta clave.
   6. Establecer el `payload` a esta forma exacta:

      ```md
      <purpose>
      Dirección efímera: <delegate-address>
      Expiración: <date>
      ```
   7. Establecer el `firma` campo al `payload` firma de la clave anterior (usuario o delegado).
   8. Repetir para todos los delegados sucesivos.
3. Agregar el paso de autorización de la acción:
   1. Establecer el `type` a un valor válido ([ver más abajo](#types))
   2. Establecer el `payload` al valor específico del tipo (como el ID de entity).
   3. Establecer el `firma` campo al `payload` firma de la clave anterior (usuario o delegado).
4. Enviar la cadena de autenticación al verificador.

### Verificación

Los servidores de contenido y servicios de terceros que implementen la verificación siguen estos pasos:

1. Verificar identificación:
   1. Verifica que el `type` es `SIGNER`.
   2. Verifica que el `payload` es la dirección de Ethereum del usuario.
   3. Verifica que el `firma` es una cadena vacía.
2. Verificar delegados:
   1. Verifica que el `type` es `ECDSA_EPHEMERAL`.
   2. Verifica que el `payload` está en esta forma y extraer los campos:

      ```md
      <purpose>
      Dirección efímera: <delegate-address>
      Expiración: <date>
      ```
   3. Verifica que el `fecha` aún está en el futuro.
   4. Verifica que el `propósito` es compatible con tu servicio.
   5. Verifica que el `firma` es válido para el dado `payload` y la clave pública previa.
   6. Repetir para todos los delegados sucesivos.
3. Verificar autorización de la acción:
   1. Verifica que el `type` es un valor válido ([ver más abajo](#types)).
   2. Verifica que el `payload` es válido para este `type`.
   3. Verifica que el `firma` es válido para el dado `payload` y la clave pública previa.
4. Aceptar la cadena de autenticación.

### Tipos y Propósitos de Acción Estándar <a href="#types" id="types"></a>

El `type` y `payload` los valores para identificación y delegación son estándar y deben verificarse como se establece arriba, pero los clientes y servicios pueden acordar cualquier `type`, y su `payload` estructura, así como establecer un `propósito` para sus claves delegadas que consideren válido.

El protocolo define tres tipos estándar, y un propósito estándar:

**Tipo `SIGNER`**

**Debe** ser el `type` inicial en la cadena, donde `payload` es la dirección de Ethereum del usuario y `firma` es una cadena vacía.

**Tipo `ECDSA_EPHEMERAL`**

**Debe** ser el `type` para pasos intermedios en la cadena, donde `payload` está en la forma descrita arriba.

**Tipo `ECDSA_SIGNED_ENTITY`**

El `type` final en la cadena para autorizar despliegues de entity, donde `payload` es el ID de una entity poseída por el usuario.

**Propósito `Decentraland Login`**

El `propósito` habitual para World Explorers, firmado tanto al iniciar sesión en el mundo como al renovar su clave delegada.
