Ir al contenido

Variables

Un entorno es un conjunto de variables con nombre guardado como JSON. Un workspace puede tener cualquier cantidad de entornos; uno está “activo” a la vez. El entorno activo se registra en el archivo de estado personal del workspace, así sobrevive a los reinicios; si ese entorno ya no existe, Fetchpier cae al primero disponible.

Las variables se usan en:

  • Placeholders {{name}} en la URL, las cabeceras, el body y los campos de formulario.
  • Campos de auth — el token Bearer, las credenciales Basic y los valores de API key pueden todos referenciar variables. La contraseña de Basic auth es un campo secreto enmascarado: un valor literal se oculta mientras tipeás (con un breve reveal del último carácter), y el valor se muestra en texto claro solo cuando es exactamente una referencia {{variable}} completa — cualquier otro valor, incluido un literal que empiece con {, queda enmascarado.
  • Passphrases de TLS — la passphrase de un certificado de cliente de workspace puede ser un placeholder {{name}}, plano o secreto, así las credenciales quedan en el entorno y no en archivos commiteados. Los certificados globales de la app siguen siendo solo literales — mirá TLS y certificados.

Dondequiera que se tipee un secreto detrás de un enmascarado —la passphrase del certificado, la contraseña de Basic auth, la contraseña del proxy— aplica la misma regla: los caracteres se ocultan, y el último carácter tipeado se muestra brevemente para ayudarte a confirmar lo ingresado. En los campos que además aceptan variables (la passphrase del certificado de workspace y la contraseña de Basic auth), el valor se muestra en texto claro solo cuando es exactamente una referencia {{variable}} completa; cualquier otro valor queda enmascarado — la misma regla que decide la advertencia de passphrase literal en texto claro, así las dos nunca se contradicen.

Los pre-request scripts pueden mutar variables de entorno con fp.environment.set('token', value), y Fetchpier persiste esos cambios después de la respuesta, así las solicitudes siguientes ven el valor nuevo. Cada envío tiene además un espacio scratch efímero de “variables” (fp.variables.*) que vive solo durante ese envío — útil para pasar valores entre el pre-request y el post-response script de la misma llamada sin contaminar el entorno persistido.

Para el orden de resolución cuando varias fuentes definen el mismo nombre, mirá Precedencia de variables.

El valor de una variable puede referenciar el entorno del host con {{$env.NAME}}. La referencia se resuelve en cada envío contra una cadena de fuentes fija:

  1. El archivo .env del workspace (si existe). Cuando la clave existe en .env —incluso con valor vacío— ese valor gana, incluso por sobre la shell del SO.
  2. El entorno del proceso Fetchpier (o fp) en ejecución.
  3. La cadena vacía cuando ninguna de las fuentes define la clave. La solicitud igual sale, con el hueco sin resolver visible en el payload saliente (p. ej. Authorization: Bearer ).

Esta es la forma soportada de mantener el config.json de un entorno commiteable sin dejar secretos en el repositorio: el JSON contiene "apiKey": "{{$env.OPENAI_KEY}}", y el secreto vive en .env (ignorado por Git por default) o en la shell del operador.

{{$env.NAME}} se reconoce solo dentro de los valores de variables de entorno. Puesto directamente en la URL, una cabecera, el body o un script de un .http queda literal — los entornos son el único lugar canónico para los secretos.

El archivo .env usa el formato dotenv: KEY=VALUE por línea, quoting "…" (con escapes \n \r \t \\ \") y '…' (literal), comentarios # al inicio de línea o inline después de un espacio, líneas vacías ignoradas, duplicados resueltos por last-wins. La expansión de variables dentro de .env no está soportada. Los archivos de más de 1 MiB o que no sean UTF-8 se ignoran con una advertencia. No hay watcher: cada envío vuelve a leer el archivo.

El editor de entornos siempre muestra el valor crudo almacenado (p. ej. {{$env.OPENAI_KEY}}), nunca el valor resuelto, así el secreto vivo nunca aparece en la UI.

Variables secretas (encriptadas, commiteables)

Section titled “Variables secretas (encriptadas, commiteables)”

Cualquier variable de entorno se puede marcar como secreta. Su valor se encripta en el lugar con una clave por workspace y se guarda como ciphertext en el mismo mapa de variables que las planas, así el entorno —credenciales incluidas— se puede commitear y compartir por Git sin filtrar nada. Marcar una variable como secreta reescribe su valor en el lugar, así un diff de Git de la operación muestra un solo valor cambiando, no una clave moviéndose. Los valores planos que empiezan con enc: están reservados (ese prefijo marca los secretos encriptados) y se rechazan al ingresarlos, tanto en el editor como en scripts.

Este es el complemento in-repo de {{$env.NAME}}: usá {{$env.NAME}} para mantener un secreto completamente fuera del repo, o una variable secreta para que la credencial viaje con el repo como ciphertext.

La clave del workspace. La primera vez que se marca una variable como secreta, Fetchpier genera una clave de workspace de 32 bytes y la muestra una única vez, en una forma agrupada legible por humanos (FPK1-…), para que la respaldes. Ese es el único momento en que la clave se muestra — después no hay ninguna pantalla de “mostrar clave”. La necesitan todos tus compañeros de equipo y todas tus otras máquinas; Fetchpier no puede recuperarla, así que guardala (un gestor de contraseñas) y compartila por un canal aparte. Un manifest del workspace commiteado en .fetchpier/secrets.json le permite a cualquier clone verificar una clave ingresada sin exponer nada.

Abrir un workspace compartido. Un clone cuya máquina todavía no tiene la clave te la pide; la clave se valida contra el manifest. Hasta que la ingreses, el workspace está bloqueado: todo funciona excepto enviar una solicitud que referencie un secreto, que falla con un error claro de “no hay clave”. Una vez ingresada, la clave se recuerda en máquinas con keyring del SO. En Linux sin keyring, Fetchpier se niega a persistirla bajo un fallback inefectivo y la mantiene solo para la sesión, volviéndola a pedir en el próximo arranque.

Usar y revelar. Una vez desbloqueado, las variables secretas se interpolan exactamente como las planas. En el editor un secreto se renderiza enmascarado con un ojo para revelarlo a demanda; en macOS con Touch ID el reveal pide confirmación con huella (con una ventana de gracia corta), y en las demás plataformas revela directamente. Un secreto también puede quedar sin valor en este workspace (un estado de “necesita valor”): su nombre y su carácter de secreto viajan por Git como plantilla, y una solicitud que lo referencie falla de forma precisa hasta que se ingrese un valor.

Enmascarado. Los valores secretos nunca aparecen en ningún artefacto que Fetchpier escriba. El log de actividad, todos los reporters de CLI y las vistas de solicitud resuelta renderizan un secreto como {secret:<name>} y marcan la entrada como redactada; el valor real va solo por la red. Si un servidor devuelve un secreto en su respuesta, Fetchpier lo enmascara en la respuesta logueada en la medida de lo posible. Los scripts son código confiable, así que un script que lea el plaintext de un secreto y lo transforme puede producir salida que el enmascarado no reconozca.

Rotación. “Rotar la clave del workspace” genera una clave nueva, reencripta atómicamente cada secreto de todos los entornos, y muestra la clave nueva una vez para que la redistribuyas. La rotación no revoca a quien ya tenía la clave vieja, ni cambia las credenciales subyacentes en sus proveedores — el diálogo de confirmación aclara ambas cosas. De la misma forma, encriptar una variable que ya tenía un valor lo protege de ahí en adelante pero no elimina las copias que ya estén en el historial de Git; si alguna vez se pusheó, rotá la credencial en su proveedor. El editor muestra esta nota antes de encriptar.

Eliminar un secreto. Una fila secreta ofrece una acción directa de eliminar (papelera), así una credencial se puede quitar en un solo gesto — sin convertirla primero a texto plano. Eliminar quita la variable como ciphertext (nunca se desencripta, y funciona incluso con el workspace bloqueado) y también quita cualquier valor local definido para ese nombre en esta máquina. La confirmación es honesta sobre la reversibilidad: para un secreto encriptado dice claramente que el valor no se puede recuperar sin el original (y nunca muestra el valor); para un secreto en “necesita valor” es más liviana, ya que no hay nada encriptado que perder. Eliminar un secreto nunca toca la clave del workspace, aunque fuera el último secreto — la custodia de claves vive solo en la pestaña Workspace keys. Esto es distinto de volver plano un secreto, que lo convierte en una variable en texto plano commiteada y conserva la fila.

Una clave filtrada (no el ciphertext) es el único accidente contra el que la encriptación no puede defenderte. Se provee una regla de scanner copiable para el formato FPK1-, así los equipos pueden detectar una clave commiteada por error.

Una pestaña Workspace keys en la configuración general lista cada clave de workspace que tiene esta máquina, mostrando de cada una su pista, su id de clave corto, cuándo se usó por última vez, y cómo está guardada (“Stored” o, en modo degradado, “This session only”). Recorrer la lista nunca pide un keychain ni una passphrase — muestra solo metadata y nunca revela, copia ni exporta una clave. Para cada clave, un estado indica si algún workspace que esta app conoce todavía la referencia: “In use” (nombrando los workspaces), “Not referenced” (nunca expresado como inválida o sin uso — un clone que esta app nunca vio puede seguir necesitándola), o “Could not check” cuando no se pudo leer un workspace conocido. Desde la pestaña podés:

  • Eliminar una clave — con resguardos, porque la eliminación puede ser definitiva. Si se sabe que la clave está en uso por un workspace que esta app referencia, la eliminación queda bloqueada, con la indicación de quitar primero los secretos dependientes de ese workspace. Si no, la confirmación explica la consecuencia claramente — la clave existe solo en esta máquina, así que cada secreto encriptado con ella se vuelve irrecuperable para siempre salvo que se vuelva a ingresar su backup de única vez —, muestra el nombre del workspace afectado como texto copiable, y habilita la eliminación solo cuando tipeás ese nombre para confirmar. La ausencia de una referencia conocida nunca bloquea la eliminación: no se puede descartar un clone que esta app nunca vio, así que ese caso pasa a la confirmación tipeada en lugar de a un bloqueo duro.
  • Agregar una clave por adelantado — pegá una clave FPK1-… (con una pista opcional) antes de clonar su workspace, p. ej. una que un compañero compartió durante el onboarding. La clave se verifica contra errores de tipeo (checksum) al ingresarla; cuando más adelante se abre el workspace, se desbloquea sin pedir nada y su estado pasa a “In use”. Volver a pegar una clave que ya tenés no hace nada; el caso raro de una clave distinta bajo el mismo id (o de una copia guardada que se volvió ilegible) ofrece reemplazarla.

Cada entorno tiene dos capas de valores, mostradas una al lado de la otra en el editor como una columna Shared y una columna Local:

  • Shared es el entorno del equipo — commiteado y compartido por Git, tanto variables planas como secretas.
  • Local es una capa superpuesta por máquina que nunca se comparte. Está excluida de Git por default y contiene dos tipos de valores: un override personal de una variable compartida, y una variable no compartida, que existe en tu máquina y en ningún lado del archivo del equipo. Cuando ambas capas tienen un valor para un nombre, gana el local.

Un valor solo viaja de la capa compartida a la local, nunca al revés. Destildar Sync copia el valor del equipo a tu capa local; nada copia un valor local hacia arriba. La única forma de que un valor llegue al equipo es que vos lo tipees en la celda Shared. Esa única regla es la que hace seguro a cualquier otro gesto: ningún checkbox, ninguna acción masiva y ningún script pueden publicar un valor privado en el archivo que tu equipo commitea.

El carácter de secreto es una propiedad de la variable, no de una capa: marcar una variable como secreta la hace secreta en ambas columnas a la vez. Un valor local de una variable con nombre secreto se encripta con la misma clave de workspace; un valor local de una variable plana se guarda como texto plano, ya que el archivo es tuyo y nunca sale de la máquina.

Dos caminos escriben la capa local, y solo la capa local:

  • Scripts. fp.environment.set(name, value) escribe en la capa local y persiste entre reinicios — el uso canónico es un pre-request script que refresca un access token para el próximo envío. Los scripts nunca escriben el archivo compartido del equipo.
  • El editor. Cada fila de variable lleva un check Sync. Tildado significa que la variable sigue el valor compartido y la celda Local es de solo lectura, así no podés divergir por accidente al tipear. Destildarlo es el acto deliberado de divergir: crea un valor local sembrado con el valor compartido actual (o, para un secreto en “necesita valor”, un campo vacío para tu propia credencial). Volver a tildarlo devuelve la variable al valor compartido actual del equipo, descartando el tuyo — pide confirmación solo cuando los dos realmente difieren. Una acción Sync all devuelve todas las variables divergidas de una sola vez.

Las variables no compartidas —un nombre en tu capa local sin contraparte en el archivo del equipo— se tratan como un estado sin resolver, no como un tipo de variable. La fila se ubica al final de la lista con su celda Shared vacía diciendo “Not shared — type to share”, una barra de acento en su borde delantero, y un tooltip que lo explica. Tipear un valor en su celda Shared le da al equipo esa variable mientras tu valor local queda y sigue ganando para vos; tildar Sync descarta el valor local y avisa primero que la variable va a quedar vacía, señalando que tipear antes un valor compartido lo preservaría. Nada más escribe el archivo del equipo: editar otras variables, reordenar, abrir y cerrar el editor, y enviar solicitudes dejan un nombre no compartido exactamente donde está.

Volver secreta una variable no compartida encripta tu valor local en el lugar y marca la variable en el archivo del equipo como un secreto que necesita valor — cada compañero pone el suyo. Bloquearla declara el carácter de secreto, no la comparte; tu valor no se publica. Eliminar una variable la quita de ambas capas, así no puede volver como una fila no compartida.

Los valores locales son personales y regenerables, lo que da forma a dos comportamientos alrededor de la clave del workspace. En una rotación —hecha acá o por un compañero cuyo cambio pulleaste— Fetchpier reencripta silenciosamente tus valores locales encriptados a la clave nueva la próxima vez que carga el entorno; si la clave vieja ya no está en la máquina, los valores locales afectados se descartan con un aviso por única vez y la variable cae a su valor compartido. Correr fp run desde la línea de comandos lee y aplica los valores locales de forma idéntica pero nunca los reescribe: en CI, un valor local desactualizado simplemente se advierte y se ignora para esa corrida, así una corrida nunca modifica un workspace checkouteado.

Variables dinámicas (generadas por el sistema)

Section titled “Variables dinámicas (generadas por el sistema)”

Además de las variables que definís, Fetchpier ofrece un conjunto fijo de variables dinámicas que se direccionan como {{$name}}: tokens integrados que resuelven a datos aleatorios recién generados en el momento del envío, así podés poner un valor descartable (una clave de idempotencia única, un UUID fresco para un body de POST, el timestamp actual en una cabecera) justo donde se consume, en lugar de hardcodear un literal o escribir un script.

El conjunto v1 es puramente algorítmico, sin datos curados: {{$guid}} / {{$randomUUID}} (un UUID v4), {{$timestamp}} (segundos UNIX) e {{$isoTimestamp}} (ISO-8601 UTC), {{$randomInt}} (0–1000), {{$randomBoolean}}, {{$randomAlphaNumeric}} (un carácter), {{$randomHexColor}}, {{$randomIP}} / {{$randomIPV6}}, {{$randomMACAddress}}, {{$randomPassword}} (15 caracteres) y {{$randomSemver}}. Los nombres son case-sensitive.

  • Frescos siempre. Cada aparición textual genera su propio valor, y cada envío regenera — {{$guid}} en una cabecera y en el body da dos UUID distintos en el mismo envío. Nada se guarda: el archivo .http siempre muestra el token, nunca un valor generado, y ningún entorno se toca. El runner de línea de comandos los resuelve igual.
  • Dónde aparecen. La lista de sugerencias de {{ los muestra después de tus propias variables, en una sola lista plana, marcados con un ícono de dado y un color dedicados; tipear $ filtra la lista solo a las variables dinámicas. En los editores, un token dinámico reconocido recibe su propio tercer color de resaltado, distinto del de una variable resuelta (verde) y del de una desconocida (rojo).
  • Tokens $ desconocidos. Un {{$notARealOne}} se trata como cualquier variable sin resolver: queda literal en la red, se marca en la UI, y el envío igual procede.
  • Log de actividad. Como los valores no son secretos, el valor generado aparece sin enmascarar en el log de actividad, en los snapshots de corrida y en los reportes de CLI — un registro fiel de lo que salió por la red, aunque, siendo aleatorio, un snapshot no es re-ejecutable al mismo valor.

Todo el prefijo $ está reservado para estos tokens del sistema: un nombre de variable de usuario que empiece con $ se rechaza al ingresarlo, tanto en el editor de entornos como en scripts (fp.environment.set('$x', …) lanza error).