Pular para o conteúdo principal

Licenciamento

O backend H1 Tech detecta o modo de licença no startup a partir de variáveis de ambiente (lógica em src/lib/license.ts::detectMode()). O servidor de licenças é o h1-license-server; o back consome via @hasarbrasildesenvolvimento/h1-sdk.

Modos

A precedência é estrita e offline vence: se LICENSE_FILE_PATH existe, é offline (mesmo que as vars de online também estejam setadas).

ModoDisparado porRedeEnforcement
Offline (air-gap)LICENSE_FILE_PATH presenteNenhuma — lê um .lic assinado e verifica Ed25519 localmenteSim
Online / HybridLICENSE_SERVER_URL e LICENSE_KEYactivate → heartbeat → cache criptografado como fallbackSim
Unconfigured (dev)nenhuma das acimaNenhumaSem enforcement (loga aviso; tudo liberado)

"Hybrid" não é um modo separado no back — usa as mesmas vars do online; a diferença ("hybrid") é uma flag no registro da licença + o comportamento de cache-fallback do mesmo LicenseClient.

Vars — Online/Hybrid

VarObrigatóriaDefaultPara quê
LICENSE_SERVER_URLsimURL do license server (ex.: https://license.h1tech.com.br)
LICENSE_KEYsimUUID da licença (admin UI)
LICENSE_PRODUCTnãoHSBR_ASSETSCódigo do produto (veja abaixo)
LICENSE_HEARTBEAT_MINUTESnão30Cadência do heartbeat
EVENTS_DATABASE_URLnãoPostgres do license (pg-boss / Integration Hub)

Vars — Offline

VarObrigatóriaPara quê
LICENSE_FILE_PATHsimCaminho do .lic (JWT assinado em Ed25519)
LICENSE_PUBLIC_KEY_PATH (ou HSBR_PUBLIC_KEY_JWK)recomendadaChave pública (public-key.json / JWK)
LICENSE_PRODUCTnãoFiltro de produto na validação

O client offline usa watchFile: true — trocar o .lic recarrega em ~30s, sem restart. Ao migrar para offline, comente LICENSE_SERVER_URL, LICENSE_KEY e EVENTS_DATABASE_URL.

Produtos e limites

O código do produto vai no claim aud / LICENSE_PRODUCT:

ProdutoCódigoLimites padrãoFeatures padrão
Gestão de AtivosHSBR_ASSETS10 devices, 3 printers, 50k tags ativas, 100k/mêsapi_access, custom_zpl, offline_mode
Printing ServiceHSBR_PRINTING5 printers, 200k/mêscustom_zpl
Middleware RFIDHSBR_MIDDLEWARE20 devicesapi_access
All-in-OneHSBR_ALL120 devices, 5 printers, 100k tags ativas, 200k/mêsapi_access, custom_zpl, offline_mode, pacotes, order_tracking

A licença (JWT Ed25519) carrega: tenant, aud (produto), limits (max_devices/max_printers/max_active_tags/max_tags_month), features (flags booleanas), exp/nbf, opcional machine_fingerprint (node-lock), license_type (online|offline|hybrid) e key_id. Limite 0 = ilimitado.

Não existe "tier trial" no código — validade é só valid_from/valid_until + status.

Enforcement (soft)

O modelo é soft enforcement: só estados terminais bloqueiam; estouros de quota (devices/printers/tags/prints) são medidos e avisados, nunca barrados na API.

  • Bloqueio duro só em estado terminal: revoked, suspended, expired (ou além do grace_period_days), not_yet_valid. No back, o licenseGuard responde HTTP 402 quando isLicenseActive() é falso; a API do license server responde 403 em activate/heartbeat.
  • Quotas → acima de 80% = warning, acima de 100% = critical, mas a operação segue; o back anexa os headers X-License-Warnings / X-License-Critical.
  • requireFeature() é soft — feature ausente vira aviso, não bloqueia.

Gerar/obter a licença de um deploy

Online

  1. No admin UI do license server, crie tenant + licença (produto + limites); copie a key (UUID).
  2. No host, no .env: LICENSE_SERVER_URL, LICENSE_KEY, LICENSE_PRODUCT.
  3. Suba o back → ele faz activate + heartbeat; o lease é cacheado em ./.license/cache.enc.
  4. Verifique: GET /license/statusactive: true.

Offline / on-prem (air-gap)

  1. Crie a licença no admin UI.
  2. Exporte o .lic: botão "Baixar .lic" (com fingerprint opcional p/ node-lock), ou npx tsx scripts/export-lic-file.ts <license-key> license.lic (rodando no/contra o license server).
  3. Baixe a chave pública: curl <server>/api/v1/public-key -o public-key.json.
  4. Copie license.lic + public-key.json para ./.license/ no host alvo.
  5. No .env: LICENSE_FILE_PATH, LICENSE_PUBLIC_KEY_PATH, LICENSE_PRODUCT (e remova as vars de online).
  6. Suba o back → verifica o .lic localmente, sem rede. Renovação = troca o arquivo (recarrega sozinho).
Integration Hub

O Hub pg-boss fica desligado quando EVENTS_DATABASE_URL está vazio ou o modo é offline (caso on-prem / SQL Server). Aí o uso é reportado pelo heartbeat HTTPS do SDK — e em offline puro (air-gap) não há rede, então nada é reportado.

Referência completa: h1-license-server/docs/license-modes.md e HSBR-Gestao-Ativos-Back/docs/license-integration.md.