{"id":50361453,"url":"https://github.com/idkmanager/firmar-ec","last_synced_at":"2026-06-03T08:01:03.888Z","repository":{"id":356477048,"uuid":"1232704075","full_name":"idkmanager/firmar-ec","owner":"idkmanager","description":"Firmador y verificador web de PDFs para Ecuador — firma PAdES con tu .p12 (ARCOTEL) 100% en el navegador; la llave nunca sale de tu equipo. PWA open source (AGPL-3.0) + licencia comercial. Privacy-by-design / LOPDP.","archived":false,"fork":false,"pushed_at":"2026-05-30T01:36:12.000Z","size":16515,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T02:20:48.490Z","etag":null,"topics":["agplv3","arcotel","astro","client-side","digital-signature","ecuador","electronic-signature","firma-electronica","lopdp","open-source","pades","pdf","pdf-signing","pkijs","privacy","privacy-by-design","pwa","svelte","web-crypto"],"latest_commit_sha":null,"homepage":"https://firmar.ec","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/idkmanager.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://firmar.ec/sponsors","https://idkmanager.com/sponsors/firmar-ec"]}},"created_at":"2026-05-08T07:25:20.000Z","updated_at":"2026-05-30T01:36:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/idkmanager/firmar-ec","commit_stats":null,"previous_names":["idkmanager/firma-ec","idkmanager/firmar-ec"],"tags_count":111,"template":false,"template_full_name":null,"purl":"pkg:github/idkmanager/firmar-ec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idkmanager%2Ffirmar-ec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idkmanager%2Ffirmar-ec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idkmanager%2Ffirmar-ec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idkmanager%2Ffirmar-ec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/idkmanager","download_url":"https://codeload.github.com/idkmanager/firmar-ec/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idkmanager%2Ffirmar-ec/sbom","scorecard":{"id":1247153,"data":{"date":"2026-05-08T21:55:27Z","repo":{"name":"github.com/idkmanager/firma-ec","commit":"32cf625669576c9338a9a090bcf4146d57bc025b"},"scorecard":{"version":"v5.0.0","commit":"ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4"},"score":5.3,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":-1,"reason":"no pull request found","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#ci-tests"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#cii-best-practices"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#code-review"}},{"name":"Contributors","score":0,"reason":"project has 0 contributing companies or organizations -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#contributors"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: RenovateBot: renovate.json:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dependency-update-tool"}},{"name":"Fuzzing","score":10,"reason":"project is fuzzed","details":["Info: TypeScriptPropertyBasedTesting integration found: tools/sbom/src/version.test.ts:1"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#license"}},{"name":"Maintained","score":0,"reason":"project was created in last 90 days. please review its contents carefully","details":["Warn: Repository was created in last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lighthouse.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/lighthouse.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/lighthouse.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/lighthouse.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lighthouse.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/lighthouse.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:86: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:95: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/scorecard.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/scorecard.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/scorecard.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/scorecard.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/idkmanager/firma-ec/scorecard.yml/main?enable=pin","Warn: containerImage not pinned by hash: infra/docker/landing.Dockerfile:2","Warn: containerImage not pinned by hash: infra/docker/landing.Dockerfile:17: pin your Docker image by updating caddy:2-alpine to caddy:2-alpine@sha256:834468128c7696cec0ceea6172f7d692daf645ae51983ca76e39da54a97c570d","Warn: containerImage not pinned by hash: infra/docker/pwa.Dockerfile:1","Warn: containerImage not pinned by hash: infra/docker/pwa.Dockerfile:14: pin your Docker image by updating caddy:2-alpine to caddy:2-alpine@sha256:834468128c7696cec0ceea6172f7d692daf645ae51983ca76e39da54a97c570d","Info:   0 out of  13 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   8 third-party GitHubAction dependencies pinned","Info:   0 out of   4 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":10,"reason":"SAST tool detected: CodeQL","details":["Info: SAST configuration detected: CodeQL","Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#sast"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":8,"reason":"2 out of the last 2 releases have a total of 2 signed artifacts.","details":["Info: signed release artifact: checksums.txt.sig: https://api.github.com/repos/idkmanager/firma-ec/releases/assets/415568481","Info: signed release artifact: checksums.txt.sig: https://api.github.com/repos/idkmanager/firma-ec/releases/assets/415301895","Warn: release artifact v0.1.0 does not have provenance: https://api.github.com/repos/idkmanager/firma-ec/releases/319745942","Warn: release artifact v0.0.1-f3 does not have provenance: https://api.github.com/repos/idkmanager/firma-ec/releases/319526100"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#signed-releases"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/scorecard.yml:16","Info: jobLevel 'actions' permission set to 'read': .github/workflows/scorecard.yml:17","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:10","Info: topLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:9","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:10","Warn: topLevel 'security-events' permission set to 'write': .github/workflows/codeql.yml:11","Info: topLevel 'contents' permission set to 'read': .github/workflows/lighthouse.yml:8","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:8","Warn: topLevel 'packages' permission set to 'write': .github/workflows/release.yml:11","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:8","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#token-permissions"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-j687-52p2-xcff","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-4w7w-66w2-5vf9","Warn: Project is vulnerable to: GHSA-48c2-rrv3-qjmp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2026-05-08T23:39:25.349Z","repository_id":356477048,"created_at":"2026-05-08T23:39:25.349Z","updated_at":"2026-05-08T23:39:25.349Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33854119,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agplv3","arcotel","astro","client-side","digital-signature","ecuador","electronic-signature","firma-electronica","lopdp","open-source","pades","pdf","pdf-signing","pkijs","privacy","privacy-by-design","pwa","svelte","web-crypto"],"created_at":"2026-05-30T02:01:26.401Z","updated_at":"2026-06-03T08:01:03.863Z","avatar_url":"https://github.com/idkmanager.png","language":"JavaScript","funding_links":["https://firmar.ec/sponsors","https://idkmanager.com/sponsors/firmar-ec"],"categories":[],"sub_categories":[],"readme":"# firmar.ec\n\n\u003e Firmador web de PDFs para Ecuador. 100% open source (AGPL-3.0), 100% del lado del cliente. Tu `.p12` nunca sale del navegador.\n\n[![App](https://img.shields.io/badge/app-firmar.ec-0F172A?style=flat-square)](https://app.firmar.ec)\n[![Mozilla Observatory](https://img.shields.io/badge/Mozilla_Observatory-A%2B-success?style=flat-square)](https://observatory.mozilla.org/analyze/firmar.ec)\n[![SSL Labs](https://img.shields.io/badge/SSL_Labs-A%2B-success?style=flat-square)](https://www.ssllabs.com/ssltest/analyze.html?d=firmar.ec)\n[![License](https://img.shields.io/badge/license-AGPL--3.0-blue?style=flat-square)](LICENSE)\n\n## ¿Qué es?\n\nUna PWA que firma y verifica PDFs con certificado digital `.p12` emitido por las ACEs acreditadas por **ARCOTEL**. Toda la criptografía corre en el navegador (Web Crypto + WebAssembly); el archivo y la llave nunca tocan un servidor.\n\n- **App**: \u003chttps://app.firmar.ec\u003e\n- **Sitio institucional**: \u003chttps://firmar.ec\u003e\n- **Comparación honesta vs FirmaEC (MINTEL)**: [`docs/COMPARATIVA.md`](docs/COMPARATIVA.md)\n\n\u003e **Sobre el panorama OSS en Ecuador**: FirmaEC del MINTEL también es open-source (publicada en [MINKA](https://minka.gob.ec)). firmar.ec **no es la única OSS**; es la primera **web/PWA** OSS auditable con foco en privacidad client-side estricta. Ambas son complementarias — ver comparativa.\n\n![PWA home](docs/screenshots/pwa-home.png)\n\n## Estado del proyecto\n\n\u003e **Versión actual**: landing `v0.1.36` · PWA `v0.9.2` (mayo 2026). La herramienta de firma/verificación es y seguirá siendo **gratis y open source**.\n\n| Fase  | Descripción                                              | Estado                              |\n| ----- | -------------------------------------------------------- | ----------------------------------- |\n| F1    | Landing pública (firmar.ec)                              | ✅ LIVE — v0.1.36                   |\n| F2    | Verificación PDF (PAdES B-B)                             | ✅ LIVE                             |\n| F3    | Firma con `.p12` (PAdES B-B + cuadro QR estilo FirmaEC)  | ✅ LIVE — v0.5.1                    |\n| F4    | Hardening (Mozilla A+, SSL Labs A+, CSP estricta)        | ✅ LIVE                             |\n| F6    | Sello de tiempo (RFC 3161, FreeTSA) → PAdES B-T          | ✅ LIVE — v0.6.0                    |\n| F7    | LTV (DSS + OCSP + document timestamp) → PAdES B-LT/B-LTA | ✅ LIVE — v0.7.0-rc1                |\n| —     | Contador de uso en vivo (Cloudflare Worker + KV, sin PII) + cluster de contenido SEO bilingüe ES/EN | ✅ LIVE — landing v0.1.36 |\n| F3.5  | WhatsApp inbox/outbox bidireccional                      | 🟡 Código completo, deploy pendiente |\n| F8    | Multi-firmante con flujo (workflow orchestration)        | ⏳ Scope abierto                    |\n\n## Características LIVE\n\n- **Firma local** — `.p12` jamás sale del navegador. Web Crypto + node-forge (`.p12` legacy 3DES).\n- **Perfiles PAdES** — B-B, **B-T** (TSA), **B-LT** (DSS+OCSP+CRL), **B-LTA** (document timestamp).\n- **Verificación offline** — TSL local con **17 ACEs ARCOTEL** ancladas (SHA-256 + SRI).\n- **Compatible** — firmas verificables en Adobe Reader, FirmaEC y MINKA (MINTEL).\n- **PWA instalable** — funciona offline. Share Target API: recibe PDFs desde WhatsApp/Gmail.\n- **Cuadro de firma con QR** — 240×72pt, URL `firmar.ec/#/verificar?h=\u003chash\u003e`.\n- **3 modos**: Firmar, Verificar, Paranoia (verificación estricta sin red).\n- **Contador de uso en vivo** — la landing muestra cifras reales (documentos firmados · firmas verificadas) servidas por un Cloudflare Worker + KV, **sin PII** (solo enteros, rate-limit por IP), alineado con la postura zero-knowledge / LOPDP.\n\n## Qué NO hace (out of scope hoy)\n\n- **XAdES / comprobantes SRI** — el SRI usa XAdES, no PAdES; usa FirmaEC del MINTEL.\n- **Tokens USB criptográficos** — solo `.p12` (WebUSB en evaluación).\n- **Firma en lote** — un PDF a la vez (roadmap F8 contempla flujos).\n- **Quipux integración nativa** — testable manualmente; sin workflow oficial.\n\n### Capturas\n\n| Vista                    | Imagen                                                         |\n| ------------------------ | -------------------------------------------------------------- |\n| Landing — desktop        | ![landing desktop](docs/screenshots/landing-home-desktop.png)  |\n| Landing — móvil          | ![landing mobile](docs/screenshots/landing-home-mobile.png)    |\n| PWA — Firmar (paso 1)    | ![firmar](docs/screenshots/pwa-firmar-step1.png)               |\n| PWA — Verificar (paso 1) | ![verificar](docs/screenshots/pwa-verificar-step1.png)         |\n| PWA — Paranoia           | ![paranoia](docs/screenshots/pwa-paranoia.png)                 |\n| PWA — Acerca             | ![about](docs/screenshots/pwa-about.png)                       |\n\n## Stack\n\n- **Landing**: Astro 5 + UnoCSS + tokens compartidos (`@firma-ec/ui-tokens`).\n- **PWA**: Svelte 5 (runes) + Vite 6 + UnoCSS + svelte-spa-router.\n- **Crypto**: pkijs 3.x + asn1js + node-forge (3DES legacy) + @noble/curves + Web Crypto.\n- **PDF**: pdf-lib + @signpdf v3.3.0 + pdfjs-dist v4.\n- **Tests**: Vitest + fast-check + Playwright + Stryker.\n- **Infra**: Docker Swarm IDK + Caddy 2 + Cloudflare Tunnel.\n\n## Privacidad y seguridad\n\n- Sin telemetría. Sin analytics de terceros.\n- CSP estricta (sin `unsafe-inline` en scripts, sin `eval`).\n- Service Worker custom intercepta `/share` para evitar enviar PDF al servidor.\n- 17 raíces ARCOTEL ancladas con SHA-256 y verificación SRI.\n- Threat model y críticas UI Pro Max disponibles bajo [`docs/`](docs/).\n- Política de divulgación responsable: [`SECURITY.md`](SECURITY.md).\n- Reportes privados: [GitHub Security Advisories](https://github.com/idkmanager/firmar-ec/security/advisories/new).\n\n## Supply chain (SLSA L2 con elementos L3)\n\nResumen ejecutivo — assessment completo en [`docs/slsa-conformance.md`](docs/slsa-conformance.md).\n\n- **Build Track L2 (verificado)**: provenance signed via `actions/attest-build-provenance@v2`, cosign keyless OIDC, Rekor public tlog, SBOM CycloneDX 1.6 + SPDX 2.3.\n- **L3 elements cumplidos**: ephemeral runner, non-falsifiable provenance, service-generated attestations.\n- **L3 strict gaps**: (a) hermeticidad — `pnpm install` aún accede al registry npm; (b) Source Track L3 requiere branch protection con 2-reviewer review (decisión pendiente — hoy somos solo-maintainer); (c) auditoría externa independiente del build platform.\n- **Verificación pública**: `gh attestation verify --owner idkmanager --signer-workflow .github/workflows/release.yml \u003cartifact\u003e`.\n\n## Reproducible Builds (roadmap, quick wins aplicados)\n\nEstado completo + verificación local en [`docs/reproducible-builds.md`](docs/reproducible-builds.md).\n\n- **Aplicado 2026-05-10**: `SOURCE_DATE_EPOCH` desde commit timestamp, `tar --sort=name --owner=0 --group=0 --numeric-owner --mtime=@$SDE`, `gzip -n` (strips embedded mtime/filename).\n- **Pendiente verificación bit-idéntica**: confirmar que dos runs back-to-back producen el mismo `sha256` (CI job a añadir).\n- **Pendiente cross-environment**: rebuild desde otra distro / runner.\n- **Verificación externa**: si lo intentas, abre un issue con el report de `diffoscope` — agradecemos cualquier verificación independiente.\n\n## Verificar releases con Sigstore\n\nPublic key:    \u003chttps://firmar.ec/.well-known/cosign.pub\u003e\nLatest tag:    `v0.7.0-rc1`\nTag SHA:       `9380db41291f2beadf2f3304cecf1d322963679f`\nRekor tlog:    `1497932420` · integrated `2026-05-10T19:02:23 UTC`\nSig + bundle:  `_backups/F7-deploy-2026-05-10-rc1/v0.7.0-rc1.{sig,bundle}`\n\n```bash\n# 1. Fetch the public key\ncurl -sf https://firmar.ec/.well-known/cosign.pub -o cosign.pub\n\n# 2. Pin the tag SHA you want to verify\nTAG=\"v0.7.0-rc1\"\nTAG_SHA=$(git rev-parse \"$TAG\")\necho \"$TAG_SHA\"  # debería imprimir 9380db41291f2beadf2f3304cecf1d322963679f\n\n# 3. Verify the signature against the tag SHA\ncosign verify-blob \\\n  --key cosign.pub \\\n  --signature _backups/F7-deploy-2026-05-10-rc1/v0.7.0-rc1.sig \\\n  --bundle    _backups/F7-deploy-2026-05-10-rc1/v0.7.0-rc1.bundle \\\n  --rekor-url https://rekor.sigstore.dev \\\n  \u003c(echo -n \"$TAG_SHA\")\n\n# 4. Cross-check Rekor tlog entry\nrekor-cli get --log-index 1497932420 --rekor_server https://rekor.sigstore.dev\n```\n\nSi cualquier paso falla, **no confíes en el binario** y abre un issue.\n\n## Principios\n\nSegura · Fácil de usar · Ligera · Compatible · Mobile-first · Fully responsive · Privacy by design · LOPDP-native · Open source · Auditable.\n\n## Desarrollo local\n\n```bash\ngit clone https://git.idkmanager.com/alfonso/firmar-ec\ncd firma-ec\npnpm install\npnpm -F @firma-ec/landing dev   # http://localhost:4321\npnpm -F @firma-ec/pwa dev       # http://localhost:5173\npnpm test                       # all packages\n```\n\n## Patrocinio\n\nfirmar.ec es y seguirá siendo gratis. El patrocinio no compra el servicio:\nfinancia el desarrollo, las auditorías de seguridad y la infraestructura que\nmantienen la herramienta viva y abierta.\n\n| Tier | Mensual | Anual (10% desc.) | Target |\n|------|---------|-------------------|--------|\n| 🥉 Bronze   | $50    | $540    | Freelancers, devs, microempresas |\n| 🥈 Silver   | $200   | $2 160  | Estudios contables, PYMEs, notarías |\n| 🥇 Gold     | $500   | $5 400  | Empresas medianas, cooperativas, estudios jurídicos |\n| 💎 Platinum | $1 500 | $16 200 | Corporativos, banca, aseguradoras |\n| 🏛️ Founding | $5 000+ | Negociable | Instituciones, gobierno, GADs, universidades |\n\n**Pago directo, sin intermediarios**: transferencia bancaria a IDK Manager\nCía. Ltda. con factura SRI. No usamos plataformas que retengan fondos ni\ncobren comisión. Escríbenos a **sponsors@firmar.ec** o visita\n[firmar.ec/patrocinar](https://firmar.ec/patrocinar).\n\n- Beneficios por tier → [`docs/sponsorship/benefits.md`](docs/sponsorship/benefits.md)\n- Gobernanza del programa → [`docs/sponsorship/governance.md`](docs/sponsorship/governance.md)\n- Lista de patrocinadores → [`SPONSORS.md`](SPONSORS.md)\n\n## Repos\n\n- **Source**: [git.idkmanager.com/alfonso/firmar-ec](https://git.idkmanager.com/alfonso/firmar-ec)\n- **Mirror (org)**: [github.com/idkmanager/firmar-ec](https://github.com/idkmanager/firmar-ec)\n- **Mirror (personal)**: [github.com/alfonsokuen/firmar-ec](https://github.com/alfonsokuen/firmar-ec)\n\n## Licencia\n\nfirmar.ec usa **licenciamiento dual**:\n\n- **Open source — GNU AGPL-3.0** (ver [`LICENSE`](LICENSE)): libre para usar, estudiar, modificar y redistribuir. Su *copyleft* exige que, si integras o modificas firmar.ec en un sistema que ofreces a terceros (incluido como servicio en red), publiques el código fuente completo de ese sistema bajo AGPL-3.0.\n- **Licencia comercial** (ver [`LICENSE-COMMERCIAL.md`](LICENSE-COMMERCIAL.md)): para **integrar firmar.ec en productos o servicios propietarios/cerrados con fines de lucro sin liberar tu código**, o para integraciones de empresa/gobierno con SLA, soporte, API o emisión de certificados. Contacto: **info@idkmanager.com**.\n\nUsar la app web tal cual (firmar/verificar) es y seguirá siendo **gratis**, también para empresas e instituciones.\n\n## Créditos\n\nDesarrollado por [IDKmanager](https://idkmanager.com) (Ecuador).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidkmanager%2Ffirmar-ec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidkmanager%2Ffirmar-ec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidkmanager%2Ffirmar-ec/lists"}