Skip to content

Distribución de rFirma para Mac por un tap de Homebrew #2045

Open
4 of 5 issues completed
Open

Description

@sgomez

Sale de la spec #2000, que se queda con la implementación (el paquete de macOS en la entrega, #2021, y el actualizador, #2024). Esta spec es la distribución por el tap de Homebrew, que necesita pasos del titular.

Problem Statement

La spec #2000 deja rFirma para Mac compilada, publicada en la Release con firma ad hoc y capaz de actualizarse sola, pero quien tiene un Mac todavía no tiene una forma razonable de instalarla:

  • descargar el paquete de la Release a mano y abrirlo choca con Gatekeeper, que lo da por dañado, y nadie le explica qué hacer;
  • no hay un tap de Homebrew, que es como se instala en Mac el software que no pasa por Apple;
  • nada comprueba que lo publicado se instale y se desinstale bien;
  • nadie ha probado que el paso de una versión a la siguiente funcione sin firma de Apple: si Gatekeeper vuelve a avisar o si el llavero vuelve a pedir permiso.

Solution

Es el modelo del tap que tuvo tabularis (debba/homebrew-tabularis) antes de pasar a homebrew/cask, que exige notarizar, salvo su postflight de xattr -c, obsoleto en Homebrew 7.

  • rFirma para Mac se instala con brew install --cask sgomez/rfirma/rfirma desde un tap propio del proyecto, sin cuenta de Apple Developer.
  • Homebrew marca la aplicación con la cuarentena y el cask no puede quitarla: la primera vez hace falta xattr -c, que el propio brew install enseña.
  • El cask declara auto_updates: true: las versiones nuevas llegan por el actualizador de rFirma, y brew upgrade no la toca.
  • El tap se actualiza solo desde la última Release estable de rFirma; rFirma no guarda ningún secreto del tap.
  • La web de rFirma ofrece macOS como la de tabularis: Homebrew, el .dmg directo y la nota de xattr -c para la primera vez. El manual y el README del tap añaden que el llavero puede volver a pedir permiso tras una actualización y qué queda al desinstalar.
  • El CI de rFirma prueba que el cask se instala y se desinstala.
  • El titular valida a mano el paso de una versión a la siguiente.

User Stories

  1. Como persona con un Mac, quiero instalar rFirma con brew install desde el tap del proyecto, para no descargar y mover la aplicación a mano.
  2. Como persona que instala rFirma, quiero unas instrucciones cortas y claras en el tap y en la web de rFirma, para saber qué hacer en cada paso.
  3. Como persona que abre rFirma por primera vez, quiero saber que macOS me avisará porque no está firmada por Apple, y cómo abrirla igualmente con xattr -c, para no pensar que está rota.
  4. Como persona que ya instaló rFirma, quiero que las versiones nuevas lleguen solas desde la propia aplicación, para no depender de acordarme de brew upgrade.
  5. Como persona que ejecuta brew upgrade, quiero que no intente actualizar rFirma por su cuenta, para que no haya dos vías que se pisen.
  6. Como persona que actualiza rFirma, quiero que macOS no vuelva a bloquearla tras la actualización, para no repetir el paso de Gatekeeper.
  7. Como persona que firma con un certificado del llavero, quiero saber de antemano que tras actualizar macOS puede volver a pedirme permiso para usar la clave, para no desconfiar.
  8. Como persona que desinstala rFirma con brew uninstall, quiero saber qué se queda en mi Mac (la CA local y el manejador de afirma://) y cómo retirarlo desde rFirma antes, para dejar el sistema limpio.
  9. Como persona que vuelve a AutoFirma, quiero saber cómo devolverle afirma://.
  10. Como titular del proyecto, quiero que el tap se actualice solo en cada versión sin que yo lo toque, para que no se quede atrás.
  11. Como titular, quiero que rFirma no guarde ningún secreto para escribir en el tap, para no exponer nada.
  12. Como titular, quiero que una versión candidata no llegue al tap, igual que no llega a latest.json.
  13. Como responsable del proyecto, quiero que el CI instale y desinstale el cask con el paquete recién construido, para no publicar un cask roto.
  14. Como titular, quiero validar a mano una vez el paso de una versión a la siguiente en un Mac real, como se hizo en Windows (Validar a mano la actualización N→N+1 en una VM Windows #1238), para confirmar lo que el CI no puede ver.
  15. Como persona con Linux o Windows, quiero que nada de esto cambie lo que instalo.
  16. Como persona con un Mac que llega a la web de rFirma, quiero ver cómo instalarla, con Homebrew o con el .dmg, para no buscarlo en GitHub.

Implementation Decisions

Heredadas de #2000:

  • ID-548: No hay cuenta de Apple Developer. rFirma para Mac no se firma con Developer ID ni se notariza; mantiene la firma ad hoc y el hardened runtime desactivado del ADR-0040, que además deja cargar módulos PKCS#11 de terceros.
  • ID-549: Se distribuye por un tap de Homebrew propio del proyecto, con un cask que instala el .app publicado en la Release. La entrega vuelve a construir el paquete de macOS (revierte f785fe3) y el tap se actualiza en cada versión. Las instrucciones de instalación, incluido xattr -c /Applications/rFirma.app para abrir la aplicación ante el aviso de Gatekeeper la primera vez, van en la documentación del tap y en la de rFirma; la landing no anuncia macOS como instalación sin pasos.
  • ID-550: En macOS, rFirma se actualiza sola con el canal de Windows (Actualización de rFirma en Windows desde la propia aplicación #1230): la entrega publica el paquete de actualización de macOS firmado con minisign y su entrada en latest.json, y rFirma lo comprueba e instala igual que en Windows. El cask declara auto_updates: true, de modo que brew upgrade no lo toca y no hay dos vías que se pisen; rFirma no trata una instalación por Homebrew como gestionada por paquete. Es el modelo de tabularis. La descarga del actualizador no lleva la marca de cuarentena del navegador, así que el aviso de Gatekeeper solo aparece en la primera instalación; está por verificar con la firma ad hoc en la prueba manual N→N+1, como Validar a mano la actualización N→N+1 en una VM Windows #1238.

Nuevas:

  • ID-551: El tap es un repositorio propio del titular (sgomez/homebrew-rfirma), separado de rFirma, con un único cask, y se actualiza solo: un workflow programado del propio tap, que también se lanza a mano, lee la última Release de rFirma y reescribe el cask con el GITHUB_TOKEN del tap. rFirma no guarda ningún secreto del tap.
  • ID-552: El cask instala el .dmg de Apple Silicon de la Release, con su versión, su URL en GitHub y su suma. Una versión candidata no lo toca porque la última Release de GitHub nunca es una prerelease, la misma regla que latest.json. Entre dos ejecuciones programadas, el cask puede ir hasta un día por detrás de la Release.
  • ID-553: El cask no toca la cuarentena. Homebrew 7 marca todo cask con la cuarentena, sin opción para evitarlo, y da por obsoleto el postflight con código libre con el que tabularis la quitaba. El cask enseña en caveats el xattr -c /Applications/rfirma.app de la primera vez, declara auto_updates: true y trae un zap con lo que rFirma deja en la carpeta de la persona usuaria.
  • ID-554: Las instrucciones viven en el README del tap, en la web y en el manual de rFirma. La web ofrece macOS como tabularis: brew install --cask sgomez/rfirma/rfirma, el enlace al .dmg de la última Release y la nota de xattr -c /Applications/rfirma.app para la primera vez, se instale con Homebrew o con el .dmg. El manual y el README añaden que las actualizaciones las hace rFirma, que el llavero puede volver a pedir permiso tras actualizar (consecuencia de ID-548) y qué retirar desde rFirma antes de desinstalar (la CA local, el manejador de afirma://).
  • ID-554 sustituye lo que ID-549 dice de la landing: la web anuncia macOS, con la nota de xattr -c.

Testing Decisions

  • TD-139: El cask del tap se prueba en el carril de macOS del CI con brew install y brew uninstall del paquete recién construido: el .app queda en su sitio, arranca con --version y se retira limpio.
  • TD-142: El paso N→N+1 se valida a mano, en un Mac real, como Validar a mano la actualización N→N+1 en una VM Windows #1238: instalar N por el tap, actualizar a N+1 desde rFirma, abrirla sin xattr y anotar si el llavero vuelve a pedir permiso. El resultado se apunta en el ticket, sin datos personales.
  • TD-143: Que una candidata no llegue al tap lo garantiza que el script del tap lee la última Release de GitHub, que nunca es una prerelease; se comprueba lanzando el workflow del tap a mano tras la primera versión estable con macOS.

Out of Scope

Further Notes

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, an agent can pick it up

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions