Schema Functions
Schema FunctionsConstantes PHP y Variables de Entorno via Schema

Constantes PHP y Variables de Entorno via Schema

Included in the “Power Extensions” bundle

Consulta el valor de una variable de entorno o constante PHP.

Descripción

Esta extensión añade el campo global _env al esquema GraphQL, que permite obtener un valor desde una variable de entorno, o desde una constante PHP (más comúnmente definida en wp-config.php, pero también puede definirse en otro lugar).

Por razones de seguridad, el nombre de la variable de entorno y constantes a las que se puede acceder debe configurarse explícitamente.

El campo _env recibe el nombre de la variable de entorno o constante bajo el parámetro "name", y se resuelve así:

  • Si existe una variable de entorno con ese nombre, la devuelve
  • En caso contrario, si existe una constante con ese nombre, la devuelve
  • En caso contrario, devuelve null y añade un error a la salida GraphQL.

Por ejemplo, esta consulta recupera la constante de entorno GITHUB_ACCESS_TOKEN que podríamos configurar para acceder a un repositorio privado en GitHub:

{
  githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
}

Esta consulta recupera la configuración de la BD definida en el archivo wp-config.php:

{
  dbName: _env(name: "DB_NAME")
  dbUser: _env(name: "DB_USER")
  dbPassword: _env(name: "DB_PASSWORD")
  dbHost: _env(name: "DB_HOST")
}

Configurando el acceso a las constantes de entorno

Debemos configurar la lista de variables de entorno y constantes permitidas que pueden ser consultadas.

Cada entrada puede ser:

  • Una regex (expresión regular), si está rodeada por / o #, o
  • El nombre completo de la variable o constante, en caso contrario

Por ejemplo, cualquiera de estas entradas coincide con la variable de entorno "GITHUB_ACCESS_TOKEN":

  • GITHUB_ACCESS_TOKEN
  • #^([A-Z]*)_ACCESS_TOKEN$#
  • /GITHUB_(\S+)/

Hay 2 lugares donde puede realizarse esta configuración, por orden de prioridad:

  1. Personalizada: En la correspondiente Schema Configuration
  2. General: En la página de Ajustes

En la Schema Configuration aplicada al endpoint, selecciona la opción "Use custom configuration" y luego introduce las entradas deseadas:

Definiendo las entradas en la Schema Configuration

En caso contrario, se usarán las entradas definidas en la pestaña "Environment Fields" desde los Ajustes:

Definiendo las entradas en los Ajustes
Definiendo las entradas en los Ajustes

Hay 2 comportamientos, "Allow access" y "Deny access":

  • Allow access: solo las entradas configuradas pueden ser accedidas, y ninguna otra puede
  • Deny access: las entradas configuradas no pueden ser accedidas, todas las demás sí pueden
Definiendo el comportamiento de acceso
Definiendo el comportamiento de acceso

Seguridad: Accediendo a variables de entorno

La extensión aplica varias capas de protección para evitar que se expongan datos sensibles:

  • Los usuarios deben haber iniciado sesión para acceder a estos campos.

  • La lista de variables de entorno que pueden consultarse está vacía por defecto, por lo que ninguna entrada es legible hasta que se configure explícitamente.

  • Los usuarios admin tienen acceso a todas las variables de entorno.

  • Para usuarios no admin, las siguientes variables de entorno siempre tienen el acceso denegado, incluso cuando estén explícitamente permitidas en la configuración:

    Variables de entorno de WordPress:

    • AUTH_KEY
    • SECURE_AUTH_KEY
    • LOGGED_IN_KEY
    • NONCE_KEY
    • AUTH_SALT
    • SECURE_AUTH_SALT
    • LOGGED_IN_SALT
    • NONCE_SALT
    • DB_NAME
    • DB_USER
    • DB_PASSWORD
    • DB_HOST
    • DB_CHARSET
    • DB_COLLATE

    Variables de entorno con cualquiera de estos substrings en su nombre:

    • PASSWORD
    • PASSWD
    • SECRET
    • PRIVATE_KEY
    • API_KEY
    • APIKEY
    • ACCESS_KEY
    • ACCESS_TOKEN
    • AUTH_TOKEN
    • BEARER
    • CREDENTIAL
    • SALT

Seguridad: No exponer credenciales

A no ser que nuestra API GraphQL no esté expuesta públicamente (como cuando construimos un sitio estático), debemos tener cuidado para que la consulta GraphQL no exponga datos privados:

  • En la respuesta de la consulta
  • En la salida cuando ocurre un error
  • En los logs

Por ejemplo, la siguiente consulta:

{
  githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
}

...imprimirá directamente las credenciales en la respuesta:

{
  "data": {
    "githubAccessToken": "{some access token}"
  }
}

Podemos usar varias de las otras funcionalidades del plugin para hacer la consulta GraphQL segura:

  • Field to Input para inyectar el valor del entorno en otro campo mediante una variable dinámica
  • Field Response Removal para evitar imprimir el valor de la variable de entorno en la salida
  • HTTP Client para conectarse directamente a un servicio externo ya desde dentro de la consulta GraphQL

Por ejemplo, la siguiente consulta se conecta a la API REST de GitHub usando un token de acceso privado:

{
  githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
    # This directive will remove this entry from the output
    @remove
 
  # Create the authorization header to send to GitHub
  authorizationHeader: _sprintf(
    string: "Bearer %s",
    # "Field to Input" feature to access value from the field above
    values: [$__githubAccessToken]
  )
    # Do not print in output
    @remove
  
  # Use the field from "Send HTTP Request Fields" to connect to GitHub
  gitHubArtifactData: _sendJSONObjectCollectionHTTPRequest(
    input: {
      url: "https://api.github.com/repos/GatoGraphQL/GatoGraphQL/actions/artifacts",
      options: {
        headers: [
          {
            name: "Accept"
            value: "application/vnd.github+json"
          },
          {
            name: "Authorization"
            # "Field to Input" feature to access value from the field above
            value: $__authorizationHeader
          },
        ]
      }
    }
  )
}

En esta consulta, los campos githubAccessToken y authorizationHeader (que contienen datos sensibles) se eliminan ambos de la salida, y el campo gitHubArtifactData ya imprimirá los resultados de la llamada a la API, sin filtrar ninguno de sus inputs (por ejemplo: un error imprimirá el string "$__authorizationHeader" en lugar del valor de la variable).