Pular para o conteúdo principal

Configuração do Servidor

Todas as chaves que o Servidor lê, o padrão de cada uma, se um Administrador pode alterá-la em tempo de execução e se uma alteração exige reinício. O Workstation Service e o Tray App são configurados à parte: veja Configuração das estações de trabalho.

De onde vem um valor​

Seis fontes, da menor para a maior precedência. Uma fonte posterior prevalece sobre uma anterior, chave por chave:

FonteOnde existe
1appsettings.jsonEmbutido na imagem. Não é um arquivo que a implantação edita.
2appsettings.{ASPNETCORE_ENVIRONMENT}.jsonO appsettings.Development.json está na imagem e fica inerte porque uma implantação não é o ambiente Development. Nunca execute uma implantação como Development: esse arquivo contém a licença de exemplo do PKI SDK e as credenciais de um Signer de teste compartilhado.
3User secretsSomente na máquina de um desenvolvedor.
4Variáveis de ambienteO container: o environment: do Compose ou os application settings do App Service. __ substitui :.
5Linha de comandoNenhum dos dois cenários usa.
6Os overrides que um Administrador salvouUma tabela no banco de dados da plataforma, lida na inicialização e relida sempre que uma configuração é salva na tela Configurações e usuários.

A fonte 6 é silenciosa e prevalece. Se você define uma das sete chaves que aceitam override na implantação e o valor não tem efeito, alguém salvou um valor na tela Configurações e usuários; o seu valor é o padrão para o qual a chave volta quando o override é limpo.

Chave que um Administrador pode sobrescreverPadrão
Sessions:DefaultDuration1 h
Sessions:MaxDuration24 h
Sessions:PinPromptTimeout60 s
Sessions:MaxPinFailures5
Sessions:PinFailureWindow15 min
Signing:WorkstationReconnectGrace15 s
Audit:RetentionDays365

Essas sete entram em vigor sem reinício. Uma linha salva com qualquer outra chave é ignorada, e não aplicada. Trate todas as outras chaves desta página como exigindo reinício.

Como escrever uma chave​

: num arquivo, __ no ambiente:

{ "Sessions": { "MaxDuration": "12:00:00" } }
environment:
Sessions__MaxDuration: "12:00:00"
az webapp config appsettings set -g <rg> -n <app> --settings Sessions__MaxDuration=12:00:00
  • Um único sublinhado não faz nada: Sessions_MaxDuration é uma variável que o Servidor nunca lê.
  • Uma lista é indexada, e o índice faz parte da chave: KeyRingProtector__RetiredCertificates__0__Certificate.
  • Uma duração é [d.]hh:mm:ss, e as horas precisam ficar abaixo de 24. 24:00:00 são vinte e quatro dias; um dia é 1.00:00:00.
  • Um tamanho é uma contagem simples de bytes. Um booleano é true ou false, em minúsculas.
  • Uma categoria de log mantém os pontos: Logging__LogLevel__TrustBridge.Server.Common.Vault.

Banco de dados e chaveiros​

ConnectionStrings:TrustBridge​

Padrão uma string local com autenticação do Windows, só para desenvolvimento · Override pelo Administrador não · Exige reinício sim

O único banco de dados da plataforma: schema, Trilha de Auditoria, os dois chaveiros e os overrides do Administrador. O padrão da imagem não funciona no Linux, então uma implantação que esquecer esta chave tem a inicialização recusada depois de cerca de noventa segundos de tentativas.

Um Command Timeout na string é o padrão, e não um teto para tudo. Alguns comandos têm limite próprio, qualquer que seja o valor da string: a aplicação do schema, o probe de saúde, a transferência ou a exclusão de um pacote de Versão da Estação de Trabalho e cada gravação na Trilha de Auditoria, que recebe quinze segundos. Command Timeout=0, que significa sem limite, continua valendo para todo o resto.

No PostgreSQL, ela segue a grafia do Npgsql (Host=, Username=, SSL Mode=), com Database:Engine definida como PostgreSql ao lado; uma string que só o driver do SQL Server lê recusa a inicialização. Ela aponta para o próprio PostgreSQL, e não para um pooler em modo de transação (o do PgBouncer, ou o do Azure Database for PostgreSQL na porta 6432): o lock da etapa do schema é mantido por uma única sessão do banco, e um pooler assim executa os comandos de uma conexão em várias. Duas chaves valem a pena nela: SSL Mode=Require ou mais rigorosa para qualquer banco que a conexão precise sair do host para acessar, porque o padrão do Npgsql volta para texto simples quando o servidor não oferece TLS; e GSS Encryption Mode=Disable, porque a imagem não traz biblioteca Kerberos, e sem ela a primeira conexão procura uma e o log ganha um erro Cannot load library libgssapi_krb5.so.2 que não muda nada.

# Docker on Linux, SQL Server beside it
ConnectionStrings__TrustBridge: >-
Server=sqlserver,1433;Database=TrustBridge;User Id=sa;
Password=${MSSQL_SA_PASSWORD};Encrypt=True;TrustServerCertificate=True
# Docker on Linux, PostgreSQL beside it
Database__Engine: PostgreSql
ConnectionStrings__TrustBridge: >-
Host=postgres;Port=5432;Database=trustbridge;Username=trustbridge;
Password=${POSTGRES_PASSWORD};GSS Encryption Mode=Disable
# Azure App Service, managed identity
ConnectionStrings__TrustBridge="Server=tcp:<sqlserver>.database.windows.net,1433;Database=TrustBridge;Authentication=Active Directory Managed Identity;Encrypt=True"

Database:Engine​

Padrão SqlServer · Override pelo Administrador não · Exige reinício sim

O mecanismo de banco de dados em que roda o banco deste Servidor: SqlServer (SQL Server ou Azure SQL) ou PostgreSql (PostgreSQL 16 ou posterior, sem nenhuma extensão), sem diferenciar maiúsculas de minúsculas. Desde o Servidor 1.20.0 os dois drivers vêm na mesma imagem, e esta chave escolhe qual o Servidor usa. Uma implantação escolhe o mecanismo uma vez, na instalação: nenhuma implantação muda de mecanismo, e apontar uma implantação existente para o outro é apontá-la para um banco de dados diferente e vazio, sem administradores, sem trilha e com um cofre que nunca guardou nada. Nada move os dados de uma instalação em funcionamento de um mecanismo para o outro.

O PostgreSQL só é suportado na forma com Docker. A forma com App Service continua no Azure SQL, com a identidade gerenciada. Nada no Servidor recusa o PostgreSQL ali, então deixe esta chave no padrão no App Service (Azure App Service).

Uma connection string escrita para o outro mecanismo recusa a inicialização, com uma linha Critical citando esta chave e ConnectionStrings:TrustBridge, antes de qualquer acesso ao banco. O mesmo vale para um valor que não cite nenhum dos dois mecanismos, inclusive um número ou dois nomes separados por vírgula. Uma string mínima como Server=…;Database=…;User Id=…;Password=… é lida pelos dois drivers e passa; a recusa é para uma string que só o outro mecanismo lê: Host=, Username= ou SSL Mode= com SQL Server, Encrypt=, Data Source= ou Initial Catalog= com PostgreSQL.

No PostgreSQL, o Servidor cria o banco de dados quando ele não existe, como faz no SQL Server, conectando-se ao banco postgres para isso; então a identidade precisa de CREATEDB nessa primeira inicialização, ou um DBA cria o banco vazio antes. Aplicar migrações exige CREATE no schema public (ou ser dono dele). Para aplicá-las manualmente, informe também o mecanismo à ferramenta (Instalação do Servidor):

dotnet ef database update --project src/TrustBridge.Server \
--connection "Host=…;Database=trustbridge;…;Command Timeout=3600" -- --Database:Engine=PostgreSql
environment:
Database__Engine: PostgreSql

Database:MigrateOnStart​

Padrão true · Override pelo Administrador não · Exige reinício sim

Se o Servidor aplica as migrações pendentes ao banco de dados na inicialização, antes de atender qualquer coisa. false não significa "iniciar mesmo assim": uma migração pendente, nesse caso, recusa a inicialização, citando as migrações e o comando a executar. Dois estados recusam a inicialização qualquer que seja o valor: um banco de dados com migrações que este build não contém, e um banco de dados que não pode ser acessado em cerca de noventa segundos. Aplicar migrações exige db_ddladmin (no PostgreSQL, CREATE no schema public); um banco de dados atualizado não precisa de nenhum DDL.

Três limites de tempo são constantes, e não chaves: cerca de noventa segundos para o banco de dados começar a responder, cinco minutos para a migração de outro processo terminar e trinta minutos para cada comando de uma migração. No Azure App Service, o WEBSITES_CONTAINER_START_TIME_LIMIT (padrão de 230 s) é atingido primeiro; aumente-o para 1800.

KeyRingProtector:Certificate​

Padrão não definido · Override pelo Administrador não · Exige reinício sim

Obrigatória em toda implantação, inclusive numa que não guarda certificados próprios. Um PKCS#12 codificado em base64, numa única linha e sem header PEM, com uma chave privada RSA. Não é um caminho nem um thumbprint. Quatro recusas impedem o host de iniciar: não configurada, não é base64, não pôde ser aberta (senha errada ou não é um PKCS#12) e nenhuma chave privada RSA utilizável. Veja Segurança.

environment:
KeyRingProtector__Certificate: ${KEY_RING_PROTECTOR_CERTIFICATE:?set KEY_RING_PROTECTOR_CERTIFICATE in .env}
# App Service: an app setting, or better, a Key Vault reference
KeyRingProtector__Certificate="@Microsoft.KeyVault(SecretUri=https://<vault>.vault.azure.net/secrets/<name>/)"

KeyRingProtector:CertificatePassword​

Padrão não definido · Override pelo Administrador não · Exige reinício sim

A senha que abre o protetor. Ausente significa que o PKCS#12 não precisa de senha, que é o padrão honesto para um protetor fornecido como configuração.

KeyRingProtector:RetiredCertificates:{n}:Certificate e …:{n}:CertificatePassword​

Padrão vazio · Override pelo Administrador não · Exige reinício sim

Protetores que esta implantação já usou para selar, mantidos para que o material de chave selado com um deles continue legível. Só para decifrar, e mantidos permanentemente: a rotação nunca re-cifra as chaves armazenadas. É uma lista de objetos, porque cada PKCS#12 aposentado tem a própria senha, pareada pelo índice. Não coloque uma entrada vazia em templates: uma entrada cujo Certificate resulta numa string vazia recusa a inicialização.

environment:
KeyRingProtector__Certificate: <the new one>
KeyRingProtector__RetiredCertificates__0__Certificate: <the one it replaced>
KeyRingProtector__RetiredCertificates__0__CertificatePassword: <if that one had a password>

Logs​

Logging:LogLevel:{category}​

Padrão Information, com Microsoft.AspNetCore em Warning · Override pelo Administrador não · Exige reinício sim

Os níveis de log do framework, e o único lugar em que um nível é decidido: o console, o arquivo rotativo e o Application Insights recebem exatamente as linhas que esses níveis deixam passar. Sete categorias trazem as linhas que vale a pena reconhecer, todas em Information ou acima, então o padrão já as mostra:

CategoriaO que informa
TrustBridge.Server.Common.Persistence.SchemaUpgradeQuais migrações foram aplicadas nesta inicialização, ou por que o schema foi recusado
TrustBridge.Server.Common.Persistence.SchemaGateQue os overrides do Administrador não puderam ser relidos depois da etapa do schema
TrustBridge.Server.Common.KeyRings.KeyRingPostureQual protetor está selando agora, com o thumbprint e o número de aposentados
TrustBridge.Server.Common.Vault.VaultReadinessSe o cofre está desligado, aberto ou travado fechado
TrustBridge.Server.Common.Audit.AuditLogUma linha de auditoria que não conseguiu chegar ao banco de dados, em Critical, com a própria linha
TrustBridge.Server.Common.Licensing.PkiLicenseGateQue o PKI SDK recusou a licença deste Servidor, de modo que nem a frota nem o cofre conseguem assinar até ela ser renovada, ou que não há licença e o Servidor não vai iniciar
TrustBridge.Pki.Validation.LacunaPkiRuntimeQue o PKI SDK está licenciado e pronto na inicialização, e onde ficam os caches dele. Em Error, por que uma licença configurada não pôde ser carregada

Aumente o nível de uma categoria, não o nível mínimo geral: o log de debug do framework soterra essas sete linhas.

Logging:File:Directory​

Padrão trustbridge-logs no diretório temporário do processo (/tmp/trustbridge-logs) · Override pelo Administrador não · Exige reinício sim

Onde o arquivo rotativo em JSON compacto é gravado, um por dia, com nova rotação ao passar de um gigabyte. A tela Log do Servidor do console administrativo lê esse arquivo. Vazio desliga o arquivo, que é o que um sistema de arquivos somente leitura define. Um diretório que o Servidor não consegue criar deixa o arquivo desligado durante toda a vida do processo, com um Warning; o console não é afetado.

Logging:File:RetainedDays​

Padrão 14 · Override pelo Administrador não · Exige reinício sim

Quantos dias de arquivos são mantidos. Abaixo de 1, a inicialização é recusada. É um limite de uso de disco, e não uma política de retenção: o pipeline do console é o registro.

Logging:ApplicationInsights:ConnectionString​

Padrão não definido · Override pelo Administrador não · Exige reinício sim

Uma connection string do Application Insights. Quando definida, toda linha também é enviada para lá como um trace, com o id de correlação e a categoria como dimensões personalizadas. Quando não definida, APPLICATIONINSIGHTS_CONNECTION_STRING é lida no lugar dela, então um workspace associado pelo portal do App Service não precisa de uma segunda configuração. Um valor que não seja uma connection string recusa a inicialização.

AllowedHosts​

Padrão * · Override pelo Administrador não · Exige reinício sim

O filtro de header Host do framework. Nenhum dos dois cenários precisa dele.

Para uma Assinatura de teste funcionar, uma lista aqui precisa incluir o host do loopback: localhost (ou 127.0.0.1, onde o Servidor escuta em 0.0.0.0), ou o host que TestSignature:LoopbackAddress indica. Uma execução chama o contrato do próprio Servidor com esse nome no header Host, e o filtro responde com um 400 simples a tudo o que ele não lista: toda Assinatura de teste falha, e o log diz apenas que POST /v1/sessions respondeu 400 sem envelope de erro. Isso vale tanto para a página de Assinatura de teste do console administrativo quanto para a pública.

Atrás de um proxy reverso​

Quem o Servidor acredita que está chamando. Uma implantação sem nada na frente não define nada aqui, e o App Service também não, porque usa a opção do próprio framework.

Três coisas leem o endereço de quem chama: o limite por endereço da admissão (Admission:RequestsPerAddress), o limite de desafios do Acesso com Certificado (Admin:CertificateSignIn:Enabled) e o ClientIp de toda linha de auditoria. Por padrão, é o endereço da conexão; atrás de um proxy reverso, então, é o endereço do proxy, e todos os clientes viram um só. Citar o proxy faz o Servidor aceitar X-Forwarded-For e X-Forwarded-Proto vindos dele, e de mais ninguém.

Há duas formas de ligar isso, e uma implantação usa uma delas:

ConfiguraçãoParaConfia em
ForwardedHeaders:TrustedProxiesUm proxy que você opera e consegue citar: Docker atrás de nginx, HAProxy ou um balanceador de cargaNos endereços listados, por tantos saltos quantos forem listados
ASPNETCORE_FORWARDEDHEADERS_ENABLED=trueO App Service, cujos front ends não podem ser listadosEm quem se conectar, por um salto. Só é seguro porque o container é acessível por esses front ends e por nada mais

Definir as duas recusa a inicialização. Uma implantação Docker que definiu ASPNETCORE_FORWARDEDHEADERS_ENABLED seguindo um guia antigo continua funcionando, confiando em quem se conectar, e registra um Warning na inicialização avisando disso; passe a usar a lista.

environment:
ForwardedHeaders__TrustedProxies__0: "10.0.0.5"
ForwardedHeaders__TrustedProxies__1: "10.0.1.0/24"

ForwardedHeaders:TrustedProxies​

Padrão vazio, o que significa o próprio endereço da conexão · Override pelo Administrador não · Exige reinício sim

Os proxies cujos X-Forwarded-For e X-Forwarded-Proto este Servidor considera. Cada entrada é um endereço (10.0.0.5) ou uma rede em notação CIDR (10.0.1.0/24), IPv4 ou IPv6. Uma conexão de qualquer outro lugar tem os dois headers ignorados, então um cliente que chega ao Servidor contornando o proxy não consegue informar o próprio endereço. Considerar X-Forwarded-Proto é o que dá a um proxy que termina o TLS cookies Secure e redirecionamentos de login para https://.

  • Liste o proxy, não a rede em que estão os clientes dele. Um cliente dentro de uma rede listada é tratado como proxy e pode informar o endereço que quiser.
  • É uma lista, mesmo com um item. No ambiente, toda entrada leva um índice, ForwardedHeaders__TrustedProxies__0. ForwardedHeaders__TrustedProxies=10.0.0.5 seria descartada sem aviso, então o Servidor recusa a inicialização.
  • Uma cadeia é percorrida de volta até o primeiro endereço não listado. Com um balanceador de carga na frente do proxy, liste os dois. Um proxy na borda deve substituir o X-Forwarded-For pelo endereço que viu (o $remote_addr do nginx); um proxy atrás de um balanceador listado deve acrescentar ao header (o $proxy_add_x_forwarded_for do nginx). Um proxy atrás de um balanceador que termina o TLS repassa o X-Forwarded-Proto do balanceador, em vez de trocá-lo por http.
  • Só o endereço e o esquema. X-Forwarded-Host e X-Forwarded-Prefix nunca são considerados, e o header padrão Forwarded (RFC 7239) não é lido. O proxy precisa repassar o header Host do navegador (no nginx, proxy_set_header Host $host), ou o redirecionamento de login aponta para o endereço do upstream.

A inicialização é recusada para uma lista que confiaria nos pares errados:

EntradaPor que é recusada
0.0.0.0/0, ::/0Confia em todo mundo.
Bits definidos além do prefixo, como 10.0.0.5/24É assim que uma interface imprime o próprio endereço; lida como rede, confiaria na sub-rede inteira.
Fora do formato decimal com pontos, como 010.0.0.5, 10 ou 0x0a000005O parser as lê como outras máquinas. Escreva o endereço como o Servidor o imprime.
IPv4 na forma IPv6 (::ffff:10.0.0.5)Escreva o endereço IPv4; ele também corresponde à forma dual-stack.
IPv6 link-local (fe80::…)O Servidor vê esse par com um escopo anexado, então a entrada nunca corresponderia.
Algumas redes IPv6As que o .NET 10 interpretaria erradamente como contendo clientes IPv4. Um endereço IPv6 exato é sempre seguro, assim como uma rede de /96 ou menos cujo comprimento seja múltiplo de 8 (/32, /48, /64).
Algo que não é um endereçoCitada pelo índice.
Um único valor sem índice, ou qualquer outra chave sob ForwardedHeaders (como KnownProxies)De outro modo, não seria lida por nada.
Definida junto com ASPNETCORE_FORWARDEDHEADERS_ENABLEDA opção do framework já confia em todo mundo, então a lista não restringiria nada.

Quando as linhas de auditoria continuam mostrando o proxy, leia a linha de inicialização que começa com Forwarded headers:: ela cita a lista, diz que nada é considerado, ou avisa que ASPNETCORE_FORWARDEDHEADERS_ENABLED confia em quem se conectar. Uma conexão de um par que a lista não cita só é registrada em Debug, na categoria Logging:LogLevel:Microsoft.AspNetCore.HttpOverrides; aumente o nível dela enquanto verifica de qual endereço o proxy realmente se conecta.

Configuração da implantação, e nunca uma tela: quais máquinas podem falar pelo endereço de quem chama é um fato da rede na frente do Servidor, e um valor errado é um jeito de contornar todas as regras por endereço.

O serviço de assinatura​

Onde fica o Lacuna Signer e como o TrustBridge se autentica nele. As duas coisas ou nenhuma: um Signer não configurado é uma implantação suportada, em que /v1/signatures recusa as chamadas e todo o resto funciona; um endereço sem chave recusa a inicialização.

environment:
Signer__BaseAddress: https://signer.example.com
Signer__ApiKey: My Application|43fc0da834e48b4b840fd6e8c371…
Signer__ApplicationName: My Application # only for a key that is the secret half alone
Signer__FolderId: f81d4fae-7dec-11d0-a765-00a0c91e6bf6
Signer__RequestTimeout: "00:00:10"
ChavePadrãoSignificado
Signer:BaseAddressnão definidoO endereço base do Signer. Defini-lo torna ApiKey obrigatória.
Signer:ApiKeynão definidoA única chave de API do Signer que o TrustBridge guarda em nome de todas as Aplicações Cliente, na forma completa application|secret que o Signer publica.
Signer:ApplicationNamenão definidoA parte da aplicação, só para uma chave que traga apenas o secret. Ignorada quando a chave contém |.
Signer:FolderIdnão definidoA pasta do Signer em que todos os documentos são colocados, como GUID. Não definida, é a raiz da organização.
Signer:RequestTimeout10 sO limite de uma chamada ao Signer. Um valor não positivo recusa a inicialização.

Todas exigem reinício, e nenhuma aceita override.

REST PKI Core​

Onde fica o REST PKI Core e como o TrustBridge se autentica nele: o mecanismo com que uma Aplicação Cliente assina os documentos depois que um Administrador liga Assinar documentos com o REST PKI Core no cartão dela, na tela Aplicações Cliente (Servidor 1.18.0 e posteriores). O REST PKI Core monta o PAdES em torno da única assinatura do titular e guarda o documento assinado; o Servidor o busca lá quando o cliente pede. O integrador não vê nenhuma diferença no protocolo.

As três ou nenhuma. Uma implantação que não define nenhuma delas inicia como sempre, e a tela Aplicações Cliente recusa passar uma aplicação para o REST PKI Core, com o único motivo de que ele não está configurado. Algumas sem as outras recusam a inicialização, citando o que falta. Uma aplicação que já usa o REST PKI Core num Servidor que perdeu a seção tem cada chamada de assinatura recusada antes de qualquer chave ser usada, como 500 INTERNAL_ERROR, com uma linha Error.

environment:
RestPkiCore__Endpoint: https://core.pki.rest/
RestPkiCore__ApiKey: TrustBridge|3c6a0f…
RestPkiCore__SecurityContextId: 201856ce-273c-4058-a872-8937bd547d36
ChavePadrãoSignificado
RestPkiCore:Endpointnão definidoO endereço da instância do REST PKI Core: absoluto e https, porque a chave de API vai em toda requisição, e com um caminho terminado em barra, ou o cliente descarta o último segmento e toda chamada vira um 404. Qualquer um dos dois erros recusa a inicialização.
RestPkiCore:ApiKeynão definidoA chave de API de uma aplicação do REST PKI Core com o role Worker, apresentada como X-Api-Key. É um segredo: defina-a a partir de um cofre de segredos ou de uma variável de ambiente, nunca num arquivo versionado.
RestPkiCore:SecurityContextIdnão definidoO contexto de segurança sob o qual o REST PKI Core valida o certificado do titular e assina, pelo GUID. Um valor que não é um GUID recusa a inicialização. O exemplo é o contexto padrão ICP-Brasil do REST PKI Core, PkiBrazil.

Todas exigem reinício, e nenhuma aceita override.

Uma seção que o REST PKI Core não atende é uma falha desta implantação, e não uma indisponibilidade. Uma chave que ele recusa (401), uma chave cuja aplicação não tem o role Worker (403) ou um contexto de segurança que ele não tem respondem toda chamada de assinatura com 500 INTERNAL_ERROR, com uma linha Error dizendo qual. O REST PKI Core inacessível, com falha, limitando requisições ou sem cota é 502 SIGNER_ERROR, que um cliente pode tentar de novo. Qualquer outra resposta do REST PKI Core que este Servidor não interpreta também é 500 INTERNAL_ERROR, com uma linha Error trazendo o status do REST PKI Core. O REST PKI Core é chamado pedindo respostas em inglês, para que as mensagens dele cheguem ao log no idioma do log.

O que se define do lado do REST PKI Core​

Três coisas decidem como fica um documento assinado ali, e nenhuma delas é uma chave daqui:

  • A confiança é do contexto de segurança, e não das Autoridades Certificadoras Confiáveis. O REST PKI Core valida o certificado do titular sob o contexto que SecurityContextId indica, uma vez antes de o titular ser consultado e de novo ao assinar, e recusa um certificado em que não confia como 422 CERT_NOT_ACTIVE. O veredito do próprio Servidor continua controlando toda assinatura, então os dois são consultados em sequência e podem discordar. Uma implantação cujos titulares vêm de ACs além da ICP-Brasil precisa de um contexto de segurança personalizado, criado no dashboard do REST PKI Core por um usuário com o role Manager e mantido em sincronia com a tela de Autoridades Certificadoras Confiáveis manualmente: nada reflete um no outro. O REST PKI Core também verifica a revogação na hora, então a janela de tolerância deste Servidor para uma AC inacessível não vale ali, a menos que o contexto esteja configurado para ignorar um status de revogação desconhecido.
  • A política de assinatura é da instância do REST PKI Core. ICP-Brasil AD-RB, sem carimbo de tempo, exige General:UseBrazilianPdfSigningPolicies ligada na instância (é desligada por padrão, o que assina um PAdES Basic simples) e General:DefaultSignaturePolicy mantida em Basic (WithTime acrescenta um carimbo de tempo). Numa instância própria, quem a opera define as duas; na instância hospedada da Lacuna, elas são da Lacuna, então pergunte antes de contar com a política.
  • As marcas nas páginas são da organização no REST PKI Core. O REST PKI Core pode carimbar nas páginas um link para a página dele sobre o documento antes de calcular o hash, de modo que o PDF marcado é o que o titular assina. Se ele faz isso depende da política de marcação de PDF da organização, ou então da Pdf:MarkingPolicy da instância, cujo padrão é WhenPossible. Defina-a como Never numa implantação cujos documentos não devem trazer nada além da assinatura.

O Servidor precisa acessar dois endereços do REST PKI Core, e não um. Endpoint é o endereço que ele chama. Um documento assinado é baixado de uma URL que o REST PKI Core responde, que traz um tíquete de acesso de curta duração e nunca é guardada, e o host dela é o endereço do site da própria instância, não necessariamente o endpoint configurado aqui. Uma implantação que acessa o REST PKI Core por um nome interno, ou atrás de uma lista de saídas permitidas, precisa deixar o Servidor sair também para esse endereço do site, ou todo download de um documento do REST PKI Core falha (502 SIGNER_ERROR onde ele é inacessível, 500 INTERNAL_ERROR com uma linha Error onde ele responde um 4xx), enquanto todas as assinaturas dão certo. Esse download não leva chave de API e lê no máximo o dobro de Signing:MaxDocumentBytes.

O REST PKI Core guarda o documento assinado; este Servidor não guarda nada. Por quanto tempo um documento continua disponível depende do que a instância faz, e um que ela não tem mais é 422 DOCUMENT_UNAVAILABLE, como um documento do Signer que deixou de existir. Voltar uma aplicação para o Signer é sempre permitido, e os documentos que o REST PKI Core assinou continuam disponíveis nele depois disso.

Como o prazo de assinatura limita uma chamada assinada ali​

Signing:RequestBudget cobre, como um único prazo, o upload validado do certificado na admissão e a execução de cada documento até a assinatura do titular: o tempo do upload é descontado do prazo de cada execução, individual ou em lote. A Autorização de assinatura no Tray App, numa sessão com PIN por transação "workstation", fica entre os dois e não é contada. Depois que a chave do titular assinou, a conclusão recebe um limite próprio, do mesmo tamanho do prazo, que nem o prazo nem um cliente que desiste da conexão interrompem, para que um documento assinado nunca fique abandonado no REST PKI Core por falta de tempo. Assim, uma chamada pode passar do prazo em até esse tanto depois que a chave assinou, e por isso Signing:StrandedAfter precisa ser maior que o dobro do prazo. Cada chamada ao REST PKI Core também é limitada pelo timeout de 60 segundos do próprio cliente, que não é uma chave daqui.

Sessões de Assinatura​

Cinco das sete chaves que aceitam override do Administrador estão aqui. Uma chave desta seção não é mais lida: Sessions:SignatureAllowance, cujo valor é definido por Aplicação Cliente desde o Servidor 1.17.0.

environment:
Sessions__DefaultDuration: "01:00:00"
Sessions__MaxDuration: "1.00:00:00"
Sessions__MaxPinFailures: "5"
Sessions__PinFailureWindow: "00:15:00"
Sessions__PinPromptTimeout: "00:01:00"
Sessions__PinRelayTimeout: "00:00:05"
Sessions__ExpirySweepInterval: "00:05:00"
ChavePadrãoOverrideReinícioSignificado
Sessions:DefaultDuration1 hsimnãoA janela de ociosidade concedida quando o cliente não pede nenhuma. Um valor não positivo recusa a inicialização.
Sessions:MaxDuration24 h (1.00:00:00)simnãoA maior janela que um cliente pode pedir; um pedido maior é reduzido a esse limite, e o valor reduzido é devolvido. Abaixo de DefaultDuration, recusa a inicialização.
Sessions:MaxPinFailures5simnãoComparações de PIN com falha, dentro da janela, que bloqueiam um CPF para criação de sessão, contadas por CPF somando todas as chaves de API. É também o tamanho dos limites de provas com falha descritos abaixo. Zero recusa a inicialização.
Sessions:PinFailureWindow15 minsimnãoA janela deslizante do bloqueio e o tempo de espera, e a janela em que os limites de provas com falha são contados. Um valor não positivo recusa a inicialização.
Sessions:PinPromptTimeout60 ssimnãoPor quanto tempo um pedido de PIN no Tray App fica na tela antes de a criação desistir. Quando esse prazo acaba, o Servidor tira o pedido da tela de uma máquina no protocolo 5 na hora. O Tray:PromptTimeout da própria estação de trabalho (90 s) é mais folgado de propósito, e é o que encerra um pedido que o Servidor não consegue acessar.
Sessions:PinRelayTimeout5 snãosimQuanto tempo a passagem pelo PIN em cache espera as respostas das máquinas. Todas as máquinas candidatas são desafiadas ao mesmo tempo dentro dele, e não uma de cada vez, então uma máquina que nunca responde custa isso e nada mais. A verificação da resposta de um Certificado A1 acontece depois, no Servidor. Um valor não positivo recusa a inicialização. O nome é o do antigo repasse do PIN e foi mantido por ser uma chave de configuração.
Sessions:ExpirySweepInterval5 minnãosimA frequência com que a varredura encerra no registro as sessões vencidas. Não muda nenhum veredito. Não é validada na inicialização.

Os limites de PIN com falha​

Sessions:MaxPinFailures dentro de Sessions:PinFailureWindow define três limites de uma vez. Reduzir o número aperta os três.

LimiteO que contaQuando se esgota
O bloqueio do CPFComparações de PIN com falha para um CPF, no máximo uma por requisição, somando todas as chaves de APIA criação de sessão para esse CPF responde TOO_MANY_PIN_ATTEMPTS até as falhas saírem da janela. Uma criação bem-sucedida não as zera; elas saem da janela com o tempo.
O limite de provas com falha de uma estação de trabalhoProvas de PIN (PIN Proofs) que uma máquina deu para um CPF e que não conferiram, mesmo que outra candidata tenha correspondido, exceto numa criação em que uma prova da própria máquina conferiuEssa máquina não recebe desafio de PIN nem pedido de PIN para esse CPF e é considerada inacessível para esse titular até as falhas saírem da janela. Registrado em Warning e auditado como pin.proof-budget-spent.
O limite do Cofre de CertificadosSenhas que o cofre tentou para um CPF e que não abriram nada, uma vez por criação, mesmo que outra candidata tenha correspondidoO cofre não tenta nenhuma para esse CPF até elas saírem da janela. Ele continua candidato, mas não é tentado, então o cliente recebe PIN_NOT_AVAILABLE em vez de WORKSTATION_OFFLINE. Auditado como pin.proof-budget-spent, sem citar máquina.

As falhas de uma máquina nunca contam contra outra, mas a própria máquina do titular pode ser deixada de lado antes de o bloqueio disparar: um PIN errado custa a ela uma prova com falha para cada certificado do titular que ela guarda para a sessão, enquanto o bloqueio conta uma. Um titular que se vincula por um token cujo PIN não é a senha dele no cofre também gasta o limite do cofre, e vê o cofre deixado de lado depois dessa quantidade de sessões assim dentro da janela.

Sessions:SignatureAllowance​

Não é mais lida desde o Servidor 1.17.0 · Override pelo Administrador — · Exige reinício —

Esta chave limitava todas as Sessões de Assinatura da implantação pelo número de chamadas de assinatura que cada uma podia fazer. A Franquia de Assinaturas agora é definida por Aplicação Cliente: um Administrador a define, altera ou remove no cartão da aplicação, na tela Aplicações Cliente, e uma sessão recebe a franquia da Aplicação Cliente que a criou. Uma aplicação sem franquia definida cria sessões limitadas apenas pela janela de ociosidade.

Um Servidor que encontra esta chave definida registra um Warning na inicialização e continua iniciando, citando a chave e a tela Aplicações Cliente. Qualquer valor gera o aviso, inclusive 0 e negativos, que antes recusavam a inicialização. Uma chave sem valor (null no JSON, ou uma variável de ambiente vazia ou em branco) não define nada e não gera aviso.

Atualizando uma implantação que a definia. A partir da 1.17.0, as sessões dela ficam sem limite até um Administrador definir a franquia em cada Aplicação Cliente que precisa de uma, porque nenhuma Aplicação Cliente tem franquia depois da atualização e nada traz o valor da chave para elas. Logo depois de atualizar, defina a franquia nessas aplicações (1 para um integrador que pediu sessões de uso único) e então remova a chave.

O que a franquia de uma Aplicação Cliente significa: quantas chamadas de assinatura uma sessão pode fazer antes de terminar como Esgotada (Exhausted), o que vier primeiro entre seus dois limites. Uma unidade por chamada, não por documento: um lote de cinquenta gasta uma, e uma chamada cujos documentos falharam todos antes de o certificado assinar não gasta nenhuma. Zero ou menos é recusado na tela. É concedida na criação, então alterar a franquia de uma aplicação só governa as sessões que ela criar depois. O protocolo não informa o saldo restante; a tela Sessões de Assinatura mostra o quanto foi gasto.

A superfície de assinatura​

environment:
Signing__RequestBudget: "00:01:00"
Signing__AuthorizationTimeout: "00:01:00"
Signing__MaxPendingAuthorizations: "2"
Signing__HashSignTimeout: "00:00:25"
Signing__SignerCancelBudget: "00:00:03"
Signing__StrandedAfter: "00:10:00"
Signing__StrandedSweepInterval: "00:05:00"
Signing__WorkstationReconnectGrace: "00:00:15"
Signing__ReconnectPollInterval: "00:00:00.250"
Signing__MaxDocumentBytes: "10485760"
Signing__TransportHeadroomBytes: "65536"
Signing__MaxBatchItems: "50"
Signing__SignerConcurrency: "32"
ChavePadrãoOverrideSignificado
Signing:RequestBudget60 snãoToda uma assinatura síncrona, da admissão da requisição até os bytes assinados, ou, numa sessão com PIN por transação "workstation", a partir do momento em que o titular responde ao pedido. Uma chamada de Assinatura de hash é limitada por ele como um todo. Estourar esse prazo responde SIGN_TIMEOUT. HashSignTimeout mais WorkstationReconnectGrace precisam caber nele, ou a inicialização é recusada. Um documento assinado com o REST PKI Core recebe um limite próprio para a conclusão depois que a chave assinou: veja REST PKI Core.
Signing:AuthorizationTimeout60 snãoQuanto tempo uma chamada de assinatura numa sessão com PIN por transação "workstation" espera o titular responder à Autorização de assinatura no Tray App (uma vez por chamada, inclusive num lote). Sem resposta, a chamada recebe 422 PIN_NOT_AVAILABLE (timed out) e nada é assinado. Ele corre fora de RequestBudget, então o tempo que uma pessoa gasta lendo e digitando nunca vira SIGN_TIMEOUT. Um valor não positivo, ou acima de dez minutos, recusa a inicialização: uma estação de trabalho recusa uma janela de pedido mais longa. Veja abaixo.
Signing:MaxPendingAuthorizations2nãoQuantas chamadas com PIN por transação podem esperar o titular numa mesma máquina ao mesmo tempo: por padrão, um pedido na tela e um na fila. Mais uma é respondida na hora com 422 PIN_NOT_AVAILABLE (too many calls waiting), e nada é assinado nem mostrado. Chamadas feitas uma depois da outra nunca são recusadas por ele. Abaixo de 1 ou acima de 8, recusa a inicialização.
Signing:HashSignTimeout25 snãoQuanto tempo uma assinatura de hash despachada pode levar antes de a máquina ser considerada inacessível. Bem acima dos cerca de 340 ms que um token gasta, porque a máquina pode estar ocupada com o documento de outra pessoa.
Signing:SignerCancelBudget3 snãoQuanto tempo a limpeza pode levar quando uma execução que não assinou nada encerra o documento no Signer.
Signing:StrandedAfter10 minnãoQuanto tempo uma Operação de Assinatura pode ficar Pendente antes de a varredura encerrá-la como Com falha, com RUN_STRANDED. Precisa ser maior que o dobro de RequestBudget mais SignerCancelBudget, ou a inicialização é recusada: o dobro desde o Servidor 1.18.0, porque um documento assinado com o REST PKI Core recebe, depois que a chave assinou, um limite para a conclusão do mesmo tamanho do prazo. Uma implantação que a definiu entre o piso antigo (uma vez o prazo) e o novo se recusa a iniciar, citando a chave; os padrões atendem à regra. AuthorizationTimeout fica de fora da regra de propósito: o registro de um documento só é aberto depois que a chamada dele é autorizada. Uma execução no REST PKI Core que a varredura encerra depois de a conclusão ter começado também gera uma linha Error, porque o REST PKI Core pode guardar para ela um documento assinado que nenhuma Operação de Assinatura cita.
Signing:StrandedSweepInterval5 minnãoA frequência dessa varredura. Uma passagem também roda na inicialização. Não é validada na inicialização.
Signing:WorkstationReconnectGrace15 ssimQuanto tempo uma assinatura espera a estação de trabalho vinculada voltar antes de responder WORKSTATION_OFFLINE. Numa sessão com PIN por transação "workstation", a mesma tolerância é dada mais uma vez, antes de o titular ser consultado. Zero recusa na hora e é válido; um valor negativo recusa a inicialização.
Signing:ReconnectPollInterval250 msnãoA frequência com que essa tolerância verifica de novo a presença. Um valor não positivo recusa a inicialização.
Signing:MaxDocumentBytes10 MB (10485760)nãoO maior documento que o Servidor assina, medido nos bytes decodificados. Acima do limite, responde 413 no envelope do contrato. Limita a memória, não o armazenamento. Os limites de transporte subjacentes são derivados dele.
Signing:TransportHeadroomBytes64 KBnãoFolga, além do documento codificado, para o restante do corpo da requisição.
Signing:MaxBatchItems50nãoQuantos documentos uma chamada em lote pode citar, e quantos hashes uma chamada de Assinatura de hash pode trazer. Uma chamada com mais é recusada antes de qualquer item ser assinado. Junto com MaxDocumentBytes, define o que um lote em andamento pode ocupar: 500 MB com os padrões. Na Assinatura de hash, é quantas vezes uma chamada pode usar a chave do titular, então aumentá-lo para os lotes aumenta isso também.
Signing:SignerConcurrency32nãoQuantas execuções de assinatura podem estar em andamento no serviço de assinatura ao mesmo tempo, em todo o Servidor. Um documento assinado com o REST PKI Core ocupa uma vaga, como um assinado pelo Signer. Um lote maior roda em ondas. Zero recusa a inicialização. A Assinatura de hash não passa por ele, porque não conversa com nenhum serviço de assinatura.

Todas exigem reinício, exceto WorkstationReconnectGrace.

Chamadas esperando o titular​

Numa sessão com PIN por transação "workstation", uma chamada pode levar WorkstationReconnectGrace, depois AuthorizationTimeout e depois RequestBudget. A máquina é informada dos dois últimos e guarda o PIN que recebeu por no máximo a soma dos dois (contando no máximo uma hora de RequestBudget). Uma implantação cujos titulares digitam devagar aumenta AuthorizationTimeout, e nada mais muda com isso.

Uma chamada esperando o titular mantém a vaga dela no throttling global (Throttle:ConcurrencyLimit) o tempo todo, pedido incluído. Muitos titulares deixando pedidos sem resposta ao mesmo tempo ocupam esse limite mais rápido do que as assinaturas, então uma implantação que ativa o PIN por transação para uma Aplicação Cliente movimentada conta essas chamadas contra ele, e não contra SignerConcurrency, que elas só alcançam depois que o titular responde. MaxPendingAuthorizations limita quantas uma máquina pode reter, então o máximo que uma frota pode reter é essa quantidade por máquina, por mais chamadas que um cliente dispare.

O throttling global​

Um limite para quantas chamadas do contrato o Servidor executa ao mesmo tempo, com uma fila curta à frente dele. Uma chamada descartada responde 429 SERVER_BUSY, sem Retry-After. Ele vale somente para a superfície do SignSession Contract; o canal das estações de trabalho, o console administrativo, o probe de saúde, a página inicial, a documentação, a admissão de estações de trabalho e os downloads de Versões da Estação de Trabalho ficam fora dele (os downloads têm um limite próprio). Os padrões ficam quase sete vezes acima da carga projetada: é um disjuntor (circuit breaker), não um teto de vazão.

ChavePadrãoSignificado
Throttle:ConcurrencyLimit200Quantas chamadas do contrato podem rodar ao mesmo tempo. Uma chamada ocupa a vaga enquanto a requisição dela durar, o que, numa sessão com PIN por transação, inclui o tempo que o titular leva no pedido. Zero recusa a inicialização; de propósito, não há como desligá-lo. É Signing:SignerConcurrency, e não este, que molda a vazão de assinaturas.
Throttle:QueueLimit50Quantas chamadas podem esperar por uma vaga antes de a seguinte ser descartada. Zero é válido e significa sem fila; um valor negativo recusa a inicialização.

Diagnóstico de tempos​

Diagnostics:ServerTiming​

Padrão false · Override pelo Administrador não · Exige reinício sim

Se toda resposta do SignSession Contract traz um header Server-Timing que divide a chamada nas etapas que ela alcançou: gate (a espera por uma vaga de Signing:SignerConcurrency), um valor signer-… por chamada ao Signer (ou um valor rest-pki-core-… por chamada ao REST PKI Core, para um documento que uma Aplicação Cliente assina com o REST PKI Core), workstation (a ida e volta até a máquina), as etapas ws-… da própria máquina e o total da chamada. Cada etapa vem em milissegundos, somada ao longo da chamada, com a contagem ao lado. Uma etapa que a chamada não alcançou fica de fora. Uma chamada descartada pelo throttling e um 401 não trazem o header.

Server-Timing: gate;dur=0.1;desc="n=1", signer-upload;dur=212.4;desc="n=1", …, workstation;dur=402.7;desc="n=1", total;dur=1203.7

Serve para medir uma implantação, por exemplo com um teste de carga, e fica desligado em produção: o header vai para todo chamador que tem uma chave de API, então informa a toda Aplicação Cliente quanto tempo levam o serviço de assinatura e os tokens desta implantação, e quais sessões assinam numa estação de trabalho em vez de no Cofre de Certificados.

Desde o Servidor 1.17.0, ele decide apenas se o header é enviado. Desligá-lo esconde as etapas, mas não impede que elas sejam medidas. O Servidor mede toda chamada de assinatura, qualquer que seja este valor, e grava as etapas nos details das linhas da Trilha de Auditoria que grava de qualquer forma (signing.completed ou signing.failed para um documento, hash-signing.completed ou hash-signing.failed para uma chamada de Assinatura de hash), como um membro timing e, quando a máquina informou um, um membro machineReported. Essas linhas são lidas por administradores, nunca por uma Aplicação Cliente, e os tempos do Painel vêm delas.

environment:
Diagnostics__ServerTiming: "true"

Admissão de estações de trabalho​

Quais máquinas podem pedir para entrar, quanto da fila um desconhecido pode ocupar e por quanto tempo um pedido abandonado permanece. Uma implantação padrão não define nenhuma destas. Todas exigem reinício, e nenhuma está na tela Configurações e usuários.

environment:
Admission__InstallerKeys__0: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE…"
Admission__MaxPending: "500"
Admission__RequestsPerAddress: "300"
Admission__RequestWindow: "00:01:00"
Admission__PendingExpiry: "7.00:00:00"
Admission__RequireHardwareBackedKeys: "false"
ChavePadrãoSignificado
Admission:InstallerKeysA Installer Key distribuída com o TrustBridgeAs Installer Keys com que este Servidor aceita pedidos de admissão assinados, cada uma um SubjectPublicKeyInfo DER em base64 de uma chave pública ECDSA P-256. Definir esta chave substitui o padrão, em vez de somar a ele. Liste duas durante uma troca: adicione a nova ao lado da antiga, atualize a frota e então remova a entrada antiga. Um valor que não pode ser interpretado recusa a inicialização.
Admission:MaxPending500Quantas máquinas podem estar aguardando um Administrador ao mesmo tempo. Acima disso, o pedido de uma máquina que este Servidor nunca viu é recusado. Zero recusa a inicialização.
Admission:RequestsPerAddress300Quantos pedidos de admissão um endereço de origem pode fazer por janela, com um endereço IPv6 contado pelo seu /64. É um limite contra incômodo: atrás de NAT, um escritório inteiro é um único endereço, e atrás de um proxy reverso a frota inteira conta como o proxy, a menos que ForwardedHeaders:TrustedProxies o cite.
Admission:RequestWindow1 minA janela fixa do limite acima.
Admission:PendingExpiry7 diasQuanto tempo o pedido de uma máquina fica na fila depois da última vez que o Servidor teve notícias dela. É contado a partir do último pedido, então uma máquina que continua pedindo nunca expira. A expiração não é uma recusa.
Admission:RequireHardwareBackedKeysfalseSe a admissão de uma máquina cuja Chave da Estação de Trabalho não está em hardware deve ser recusada. Essa máquina continua aparecendo na fila, e a tela explica por que o controle Admitir a recusa. A postura é uma declaração da própria máquina; nada a atesta.

O console administrativo​

O primeiro Administrador, se uma senha sozinha dá acesso ao console, se um certificado dá, e se uma senha ainda dá acesso.

environment:
Admin__Bootstrap__Email: admin@example.com
Admin__Bootstrap__Password: ${ADMIN_BOOTSTRAP_PASSWORD}
Admin__Bootstrap__DisplayName: Platform Administrator
Admin__SecondFactor__Required: "true"
Admin__CertificateSignIn__Enabled: "false"
Admin__CertificateSignIn__WebPkiLicense: ${WEB_PKI_LICENSE}
Admin__CertificateSignIn__Required: "false"

Admin:Bootstrap:Email, Admin:Bootstrap:Password, Admin:Bootstrap:DisplayName​

Padrão não definido · Override pelo Administrador não · Exige reinício sim

O primeiro Administrador. Lidas num Servidor cuja tabela de contas está vazia, e inertes em todas as inicializações seguintes: uma senha configurada nunca recria uma conta excluída nem redefine uma existente. A senha precisa atender às regras de senha da identidade, ou a conta não é criada e o motivo é registrado no log. Remova as duas depois de entrar. Com elas não definidas e a tabela vazia, o Servidor registra um Warning e não cria nada; ninguém consegue entrar no console até que algo coloque uma conta lá.

Admin:SecondFactor:Required​

Padrão true · Override pelo Administrador não, de propósito · Exige reinício sim

Se uma Conta Administrativa precisa apresentar um segundo fator além da senha. Configuração da implantação, e nunca uma tela: uma opção que desativa o segundo fator, ao alcance de dentro do console que ele protege, é uma opção que um invasor desliga no caminho. Uma linha salva no banco de dados com esta chave é ignorada. Vale para toda a plataforma, sem exceção por conta.

É também o acesso de emergência (break-glass) para um Administrador que perdeu o autenticador; o procedimento está em Segurança. A postura enfraquecida é anunciada a cada inicialização enquanto a opção estiver desligada.

Admin:CertificateSignIn:Enabled​

Padrão false · Override pelo Administrador não, de propósito · Exige reinício sim

Se o console oferece o Acesso com Certificado, com um e-CPF ICP-Brasil. O certificado é escolhido numa página própria, /admin/login/certificate, à qual um link da página de login leva, e é lido no computador da própria pessoa pelo Lacuna Web PKI, uma extensão de navegador com uma parte nativa que cada pessoa instala uma vez; só em navegadores de desktop. Num celular ou tablet, a página do certificado avisa isso. Só certificados e-CPF são listados.

Desligada, a página de login não mostra nenhum sinal dela: nenhum link, nenhuma folha de estilo própria e nenhum cookie, e quem abre a página do certificado por um favorito é mandado para a página de login. Ligada, ela precisa de Admin:CertificateSignIn:WebPkiLicense, ou o Servidor recusa a inicialização citando essa chave. Ligada ou desligada, a própria página de login não traz script nem licença; só a página do certificado traz. A página de login mantém o formulário de senha, a menos que Admin:CertificateSignIn:Required o retire.

Ligada, a página de login abre na forma de entrar que o navegador usou por último (Servidor 1.20.0 e posteriores). Uma senha ou um certificado aceitos, mesmo que depois venha a etapa do Segundo Fator, gravam um cookie, TrustBridge.SignInCredential, restrito a /admin/login e mantido por um ano, que diz qual foi. Ele não é uma credencial, não autoriza nada e sobrevive a uma saída. Um navegador cuja última forma foi um certificado é mandado da página de login para a página do certificado, a menos que o endereço cite uma recusa ou peça o formulário de senha (?usePassword=true); um seletor Senha | Certificado digital nas duas páginas deixa a outra forma a um clique. Desligada de novo, o cookie não é mais lido nem gravado.

Ligada, uma conta com CPF vinculado entra só com o certificado: sem senha e sem código do Segundo Fator. Um Administrador digita o CPF de outra conta na tela de contas, ao criá-la ou com Definir CPF vinculado na linha dela, e só enquanto esta chave está ligada; ninguém define o próprio, então ninguém entra com certificado até outro Administrador ter definido um. Uma conta que ainda não tem Segundo Fator, onde Admin:SecondFactor:Required está ligada, é levada a cadastrar um primeiro.

A página do certificado pede um desafio em /admin/login/certificate/challenge, com limite de dez por minuto por endereço de origem, e desiste de uma requisição depois de trinta segundos. Atrás de um proxy reverso, cite-o em ForwardedHeaders:TrustedProxies, ou todos os navegadores dividem os dez do proxy, e qualquer pessoa que consiga acessar a página do certificado pode esgotá-los por um minuto de cada vez.

Uma linha salva no banco de dados com esta chave é ignorada, pelo motivo de Admin:SecondFactor:Required: o que decide como uma pessoa chega ao console nunca é configurado de dentro dele.

Admin:CertificateSignIn:WebPkiLicense​

Padrão não definido · Override pelo Administrador não · Exige reinício sim

Obrigatória quando Admin:CertificateSignIn:Enabled está ligada. A licença do Web PKI, no formato de uma linha que a Lacuna emite, escrita como uma única string. Não o formato JSON: escrita como objeto, não é lida por nada, e o Servidor recusa a inicialização como se nenhuma licença estivesse definida. Não é a licença do PKI SDK (Certificates:Validation:License).

Não é um segredo. Ela é avaliada no navegador, então qualquer pessoa que carregue a página do certificado pode lê-la, e ela está vinculada aos domínios que cita. Ela precisa citar o hostname que as pessoas digitam: uma licença que não o cobre falha na primeira vez que o componente é usado, e a página do certificado informa isso como um problema de licença para o operador.

Admin:CertificateSignIn:Required​

Padrão false · Override pelo Administrador não, de propósito · Exige reinício sim

Se as senhas estão desligadas para o console administrativo. Ligada, a página de login manda todo visitante para a página do certificado, uma senha enviada mesmo assim é recusada sem nada ser verificado nem contado contra a conta, e um certificado do CPF vinculado da conta é a única forma de entrar. O cadastro do Segundo Fator num primeiro acesso com certificado funciona como funciona sem ela.

Ela exige Admin:CertificateSignIn:Enabled ligada. Ligada enquanto aquela está desligada descreve um console sem nenhuma forma de entrar, então o Servidor recusa a inicialização citando as duas chaves. É a única inicialização que esta chave recusa.

Uma conta sem CPF vinculado não consegue entrar enquanto ela está ligada, seja Administrador ou Auditor. Outro Administrador define um na tela de contas, e as senhas continuam desligadas enquanto isso. Ninguém consegue definir o próprio, então um Administrador sozinho não consegue desligar as senhas: uma implantação que faz isso precisa de pelo menos dois Administradores, cada um com um CPF vinculado que o outro definiu, antes de ligar esta chave.

Ela avisa a cada inicialização enquanto está ligada. O aviso conta quantas contas habilitadas não têm CPF vinculado, quantas delas são de Administradores e quantos Administradores habilitados existem. Quando o segundo número chega ao terceiro, ninguém consegue administrar a plataforma. Onde nenhum proxy é citado em ForwardedHeaders:TrustedProxies, o aviso também diz que todos os navegadores dividem os dez desafios por minuto do proxy, então qualquer pessoa que consiga acessar a página do certificado consegue deixar todo mundo de fora. Cite o proxy antes de ligar esta chave.

Ela é o acesso de emergência (break-glass). Quando ninguém consegue apresentar um certificado que o Servidor aceite (uma Autoridade Certificadora Confiável removida, uma licença da PKI vencida, uma licença do Web PKI que não cita mais o hostname, uma atualização de navegador que quebrou a extensão, ou o CPF vinculado do último Administrador removido), defina-a como false e reinicie: o login com senha volta sem nenhuma outra mudança. Ligue-a de novo depois; nada vai lembrar você, porque o aviso só aparece enquanto as senhas estão desligadas.

Uma sessão aberta com senha antes da mudança não é encerrada por ela. Um login com senha que estava parado na etapa do código quando o Servidor reiniciou volta para o formulário de login.

A Trilha de Auditoria​

Audit:RetentionDays​

Padrão 365 · Override pelo Administrador sim · Exige reinício não

Por quanto tempo os eventos de auditoria são mantidos; uma limpeza diária exclui as linhas mais antigas. Abaixo de 1, a inicialização é recusada: uma retenção de zero apagaria toda a trilha na passagem seguinte.

A limpeza não toca na Atividade de assinatura, as contagens do Painel: elas não citam nenhum titular e são mantidas enquanto a instalação existir, então os números "desde a instalação" sobrevivem a esta retenção e vão divergir de uma contagem das linhas de auditoria que restam. Os dois estão certos.

A limpeza nunca exclui uma linha que a Atividade de assinatura ainda não contou. Na primeira inicialização de um Servidor com a 1.17.0 ou posterior, a Atividade de assinatura é preenchida a partir de toda a Trilha de Auditoria, um bloco de cada vez, e a limpeza não exclui nada até isso terminar; depois disso, ela nunca exclui além do ponto até o qual a contagem está consolidada. Num Servidor em funcionamento esse ponto fica cinco minutos atrás do momento atual, então isso não muda nada. Só importa quando a contagem parou, ou quando o Servidor ficou parado por mais tempo que a retenção, e então a limpeza registra um aviso dizendo onde está retida e se recupera quando a contagem se recuperar.

Não há configuração para o destino de uma gravação de auditoria que falhou. Uma entrada que o banco de dados não aceita é gravada no Log do Servidor no nível Critical, com a própria linha, e o console administrativo mostra um alerta. Ela chega até você pelo pipeline de logs que a implantação tiver, então o fallback da auditoria faz parte da sua retenção de logs, e não dos seus backups.

O Painel​

O calendário em que o Painel do console administrativo lê a Atividade de assinatura (Servidor 1.17.0 e posteriores). A Atividade de assinatura é contada a partir da Trilha de Auditoria um minuto de cada vez, cinco minutos atrás do momento atual, em blocos de uma hora em UTC; esta chave diz onde começam um dia e um mês quando essas horas são lidas de volta. O atraso e a cadência não são configuráveis.

environment:
Dashboard__TimeZone: America/Sao_Paulo

Dashboard:TimeZone​

Padrão UTC · Override pelo Administrador não · Exige reinício sim

O fuso horário IANA cuja meia-noite começa um dia do Painel e cujo primeiro dia do mês começa um mês: America/Sao_Paulo para uma implantação cujos operadores leem o dia no horário de Brasília, em que um dia começa às 03:00 UTC. É o calendário da implantação, nunca o de quem lê. Um fuso que o Servidor não encontra recusa a inicialização, citando esta chave, e o mesmo vale para um id de fuso do Windows como E. South America Standard Time, cuja recusa indica o fuso IANA a escrever no lugar.

Lida uma vez, na inicialização. Alterá-la não recalcula nada: as mesmas horas em UTC são lidas em dias diferentes, então ela pode ser corrigida a qualquer momento. Num fuso cujo deslocamento não é um número inteiro de horas, a hora que contém a meia-noite conta no dia que ela começa.

Idiomas​

environment:
Language__DefaultCulture: pt-BR
Language__SupportedCultures__0: en
Language__SupportedCultures__1: pt-BR
ChavePadrãoSignificado
Language:DefaultCultureenO idioma em que é respondida uma requisição sem um Accept-Language utilizável. Não é um idioma de toda a implantação: a preferência do navegador do leitor e o seletor de idioma prevalecem. Um valor fora do conjunto suportado, ou um erro de digitação, recusa a inicialização.
Language:SupportedCulturesvazio, o que significa en e pt-BRTodos os idiomas em que as páginas respondem. Informar um conjunto substitui o padrão.

A superfície do contrato, os logs e a Trilha de Auditoria ficam permanentemente em inglês.

A documentação publicada​

Documentation:ApiReferenceEnabled​

Padrão true · Override pelo Administrador não · Exige reinício sim

Se a referência navegável é servida em /scalar. O documento legível por máquina em /openapi/v1.json é o contrato de integração, é sempre servido e não é afetado. Os dois respondem sem credencial.

A Assinatura de teste​

Se a página inicial (Landing Page) permite que um visitante faça uma Assinatura de teste: uma assinatura de verdade, pelo contrato do próprio Servidor, pelo titular do certificado e pelo Lacuna Signer (ou pelo REST PKI Core, para uma chave cuja Aplicação Cliente assina os documentos com ele), num documento de uma página que o Servidor escreve sobre o certificado. É como um operador comprova, de um navegador, que uma implantação nova funciona de ponta a ponta, e como uma demonstração mostra o produto assinando. Desligada por padrão.

Um Administrador pode fazer uma de qualquer forma, pela página Assinatura de teste do próprio console administrativo (/admin/test-signature, em Sistema), protegida pelo login administrativo e pelo segundo fator dele. Um Auditor vê ali se a página pública está ligada, e nenhum formulário. Desligada, a página pública não existe: /test-signature responde 404 e a página inicial é o que era.

Ligada, a página inicial leva a /test-signature, em que quem pede digita um CPF, o PIN dele, opcionalmente um CNPJ, a chave de API de uma Aplicação Cliente, opcionalmente um endereço de e-mail alternativo, um tempo limite e quantos Documentos assinar. A execução é uma única requisição: uma Sessão de Assinatura criada com essa chave, os dados do certificado, o documento, a assinatura dele e o PDF assinado, e a sessão encerrada no final, tenha a execução dado certo ou não. Quem pediu recebe os dados públicos do certificado e o PDF assinado, ou o que foi recusado, ou qual etapa falhou, com o código de erro do contrato ao lado de uma falha na etapa da assinatura (Servidor 1.24.0). Nenhum id de sessão ou de assinatura chega ao navegador.

Mais de um documento é uma única chamada em lote (Servidor 1.23.0): até 50, ou Signing:MaxBatchItems onde ele for menor, assinados como cópias numeradas da página numa única chamada POST /v1/signatures/batch, então com uma só cobrança da Franquia de Assinaturas e, sob o PIN por transação, uma só confirmação no Tray App para todos. Os documentos que foram assinados voltam num único ZIP, test-signatures.zip, e cada um que não foi aparece ao lado, com a etapa em que falhou; a execução conta como concluída se pelo menos um foi assinado. Um tempo limite que se esgota enquanto as cópias assinadas são baixadas mantém as que já tinham sido baixadas. Uma execução de um documento é a mesma chamada única de sempre.

  • A chave é de quem pede, e o Servidor não guarda nenhuma. Toda chamada da execução passa pela verificação da chave de API, pelo throttling global e pela Trilha de Auditoria como a Aplicação Cliente dessa chave, exatamente como a chamada de um integrador. Então uma demonstração começa entregando uma chave a alguém, e quem a tem poderia usá-la direto contra o contrato. A página devolve todos os campos preenchidos na página que responde ao formulário, a chave de API e o PIN inclusive, para que Assinar de novo seja um só clique (Servidor 1.23.0). Essa página é enviada com no-store, e uma demonstração numa máquina compartilhada termina fechando a aba. O Servidor não registra no log nem a chave nem o PIN, e esquece os dois assim que essa página é escrita.
  • Qualquer CPF pode ser tentado, e uma execução substitui uma Sessão de Assinatura já ativa para o mesmo CPF e CNPJ, como faria a criação de uma sessão com essa chave a partir de qualquer cliente; a página avisa isso ao lado do formulário. Um PIN errado conta para o bloqueio do titular. Uma execução por CPF de cada vez.
  • Uma chave cuja Aplicação Cliente tem o PIN por transação ativado funciona: numa sessão "workstation", a execução espera o titular no Tray App dentro do tempo limite dela.
  • Cada execução grava test_signature.completed, test_signature.failed (com a etapa) ou test_signature.refused (com o motivo) na Trilha de Auditoria, com o endereço de quem pediu, o CPF e o CNPJ e a Aplicação Cliente da chave, e, num lote, quantos documentos foram pedidos e, se ele foi concluído, quantos foram assinados. Nunca o PIN nem a chave.
  • A página não precisa de rota para a internet.
environment:
TestSignature__Enabled: "true"
TestSignature__MaxTimeout: "00:02:00"
ChavePadrãoOverrideSignificado
TestSignature:Enabledfalsenão, de propósitoSe a página inicial oferece uma Assinatura de teste. Governa só a página pública. Configuração da implantação, e nunca uma tela: ela coloca um formulário de assinatura na raiz do host, e uma linha salva no banco de dados com esta chave é ignorada.
TestSignature:MaxTimeout2 minnãoO maior tempo limite que quem pede pode digitar, e o valor com que o formulário começa. O tempo limite digitado limita a execução inteira e é a duração da sessão que ela cria. Um valor digitado acima deste é recusado, e não reduzido. Abaixo de um segundo ou acima de uma hora, recusa a inicialização.
TestSignature:LoopbackAddressnão definido (onde o Servidor escuta)nãoPor onde uma execução acessa o /v1 do próprio Servidor. Não definida, é um endereço em que o Servidor escuta, HTTP simples antes de HTTPS, com um binding curinga como http://+:8080 lido como http://localhost:8080. Definida, é um endereço http ou https absoluto; qualquer outra coisa recusa a inicialização.

As três exigem reinício, e MaxTimeout e LoopbackAddress são verificadas na inicialização mesmo com Enabled desligada, porque a página administrativa as usa.

Mantenha MaxTimeout abaixo do timeout de leitura do seu proxy reverso. Uma execução é uma única requisição HTTP mantida aberta até o documento assinado voltar, e um proxy que para de esperar a interrompe. O front-end do App Service encerra uma requisição depois de 230 segundos; o proxy_read_timeout do nginx é de 60 segundos, a menos que seja aumentado; o proxy da Cloudflare responde 524 aos 100 segundos. Deixe folga para o titular responder a um pedido do Tray App, para o serviço de assinatura, e 15 segundos além do valor para a execução encerrar a sessão. Atrás do padrão do nginx ou da Cloudflare, o padrão de dois minutos é longo demais. A própria página para de esperar um minuto depois do tempo limite digitado, ou com Esc, e traz o formulário de volta como ele foi enviado.

Para onde vai o loopback:

  • O App Service escuta em HTTP simples atrás do TLS da plataforma, então o padrão está certo.
  • O cenário Docker escuta só em HTTPS (https://+:8443), com um certificado emitido para o nome que os visitantes digitam, que não é localhost, então o padrão falharia em toda execução, inclusive nas da página administrativa. Acrescente um listener HTTP simples ligado ao loopback do próprio container, ASPNETCORE_URLS: https://+:8443;http://localhost:8080, e o padrão o escolhe. Nada fora do container consegue acessá-lo, e o arquivo do Compose publica só a 8443. Uma implantação atrás do seu próprio proxy já escuta em HTTP simples e não precisa de nada.
  • Qualquer que seja o host que o loopback chama, AllowedHosts precisa admiti-lo.

Atualizando a partir do Servidor 1.14.x: TestSignature:Cpfs, ApiKey, FallbackEmail, Turnstile:SiteKey, Turnstile:SecretKey e Timeout não são mais lidas (quem pede digita o que elas forneciam, não há verificação do Cloudflare Turnstile, e Timeout agora é MaxTimeout). Um Servidor que encontra alguma delas definida registra um único Warning citando-as e inicia. Remova-as e revogue a chave que ApiKey guardava na tela Aplicações Cliente: ela continua sendo uma chave válida da Aplicação Cliente dela.

O canal das estações de trabalho​

Como uma máquina admitida prova que é ela mesma a cada conexão, com uma asserção de curta duração assinada pela Chave da Estação de Trabalho, e por quanto tempo o Servidor espera ter notícias de uma máquina conectada. As duas chaves da asserção não são algo que uma implantação saudável precise mexer; ClientTimeout é para mudar uma vez, depois que a frota estiver atualizada.

environment:
Workstations__ClockSkewTolerance: "00:01:00"
Workstations__MaxAssertionLifetime: "00:05:00"
Workstations__ClientTimeout: "00:00:30"
ChavePadrãoSignificado
Workstations:ClockSkewTolerance60 sA diferença máxima entre o relógio do Servidor e o de uma estação de trabalho antes que essa máquina não consiga se conectar. Aplicada nas duas pontas. O log do Servidor cita a máquina com o relógio desviado e a diferença, positiva quando a máquina está atrás do Servidor (A workstation assertion was refused: Expired ou NotYetValid). Um valor negativo ou acima de uma hora recusa a inicialização.
Workstations:MaxAssertionLifetime5 minA maior janela de validade aceita numa asserção; uma declaração mais longa é recusada. Limita o cache de nonces, que guarda no máximo 100.000 nonces e, quando cheio, recusa em vez de esquecer. Um valor não positivo ou acima de uma hora recusa a inicialização.
Workstations:ClientTimeout30 sPor quanto tempo uma máquina conectada pode ficar em silêncio antes de o Servidor desligar a conexão dela. Veja abaixo.

Todas exigem reinício, e nenhuma aceita override.

Workstations:ClientTimeout​

Padrão 30 s (00:00:30) · Override pelo Administrador não · Exige reinício sim

Por quanto tempo uma estação de trabalho pode ficar sem que o Servidor tenha notícias dela, uma chamada ou um ping de keep-alive, antes de o Servidor fechar a conexão. A máquina então aparece offline na página da frota na próxima atualização (em até 10 s), o último contato dela é gravado e a desconexão entra na Trilha de Auditoria. Uma máquina que continua lá se reconecta sozinha. Isso só importa para máquinas que somem: um cabo desconectado, Wi-Fi perdido, a tampa de um notebook fechada, um firewall que derruba a conexão em silêncio. Uma máquina que desliga ou para o Service de forma limpa aparece offline na próxima atualização, qualquer que seja este valor.

Defina-a como 00:00:15 quando todas as máquinas rodarem uma release do Workstation posterior à 1.1.0, e não antes. O Servidor e um Workstation Service atual fazem ping a cada 5 s; o Workstation 1.0.x e o 1.1.0 fazem ping a cada 15 s, e nada que o Servidor diga muda isso. Limitadas a 15 s, essas máquinas seriam desconectadas depois de quase todo ping, e cada desconexão é uma reconexão, um handshake e um par de conexão/desconexão na Trilha de Auditoria. A coluna Versão do serviço da página da frota é onde verificar. Cada máquina para a qual o valor é curto demais é citada no log do Servidor em Warning, uma vez por conexão: procure pings every 00:00:15, but Workstations:ClientTimeout is.

Com 15 s, uma máquina que some aparece offline em cerca de 25 s; com o padrão, em cerca de 40 s. Uma máquina em long polling (atrás de um proxy que recusa WebSockets, por exemplo) não é desconectada por este timeout: ela nunca faz ping, e a conexão termina pelo timeout de ociosidade da própria camada de conexão quando as requisições de polling param.

Uma linha de desconexão na Trilha de Auditoria diz o motivo, como "reason" nos detalhes: timed-out para este timeout, closed, revoked, removed, returned-to-queue, server-stopping ou error. A aba Eventos da máquina na página da frota mostra a mesma palavra, exceto removed: uma máquina removida não tem painel, então a última desconexão dela é lida na Trilha de Auditoria, pelo id da máquina. Uma máquina em long polling que ficou em silêncio aparece como closed, por isso a linha também cita o transport dela.

Escreva no formato hh:mm:ss. Um 15 sozinho vira quinze dias, e 0:15, quinze minutos. Menos de 10 s (o dobro dos 5 s em que uma máquina atual faz ping) ou mais de 5 minutos recusa a inicialização.

Atualizar um Servidor e sua frota para o protocolo 6​

O canal está no protocolo 6 (Servidor 1.15.0, Workstation 1.6.0), que acrescenta a Autorização de assinatura: numa sessão criada por uma Aplicação Cliente com o PIN por transação ativado, o Servidor pede ao Tray App da máquina vinculada o PIN de cada chamada de assinatura. A janela deste Servidor é 5–6. Do Workstation 1.7.0 ao 1.10.0, todos continuam no protocolo 6.

MáquinaProtocoloCom o Servidor 1.15.0 ou posterior
Workstation 1.6.0 a 1.10.06Totalmente suportada. Entregue o Workstation 1.8.0 e posteriores com o Servidor 1.20.0 ou posterior, o primeiro cujo canal das estações de trabalho aceita o Relatório da Estação de Trabalho deles: um anterior encerra a conexão de um relatório do 1.8.0 acima de 32 KB, enquanto o 1.8.1 e posteriores mantêm os relatórios abaixo de 32 KB até o Servidor aceitar um, e continuam conectados. O console que o Workstation 1.10.0 informa aparece a partir do Servidor 1.23.0.
Workstation 1.5.05Conecta e atende todas as sessões como antes. Ela nunca recebe uma Autorização de assinatura, então, para uma sessão criada por uma Aplicação Cliente com o PIN por transação ativado, conta como offline: um titular nessa situação cujas máquinas estão todas no protocolo 5 recebe 422 WORKSTATION_OFFLINE, e o Servidor registra um Warning citando a máquina e o protocolo dela cada vez que a deixa de lado.
Workstation 1.4.x e anteriores4 ou menosRecusada no handshake, com Atualização necessária na linha dela na frota e na Trilha de Auditoria. Ela também não pode receber oferta de versão: atualize-a manualmente ou por Política de Grupo.

Antes de atualizar o Servidor, confira na página da frota se alguma máquina admitida ainda está no 1.4.x, e atualize-a primeiro para o Workstation 1.5.0. Depois atualize o Servidor, faça o upload de uma release no protocolo 6 e deixe a frota recebê-la. Ative o PIN por transação para uma Aplicação Cliente só quando as máquinas dos titulares dela rodarem o 1.6.0 ou posterior. Uma máquina no protocolo 6 não consegue se conectar a um Servidor anterior ao 1.15.0 (janela 4–5): ela recebe update the Server first, não recebe licença, e todo certificado aparece como UNTRUSTED no Tray App até o Servidor ser atualizado.

O que muda para os integradores: nada, a menos que a Aplicação Cliente deles tenha o PIN por transação ativado. O protocolo é do canal, não do contrato.

Atualizar um Servidor e sua frota para o protocolo 5​

Substituída num aspecto pelo protocolo 6, acima: um Servidor a partir do 1.15.0 tem a janela 5–6, então a máquina no protocolo 4 que esta seção descreve como conectando é recusada. O resto é como o protocolo 5 chegou.

O protocolo 5 (Servidor 1.13.0, Workstation 1.5.0) é a versão em que o Servidor deixa de enviar o PIN da aplicação cliente a qualquer estação de trabalho. A criação de sessão desafia cada máquina candidata com um nonce, a máquina responde com uma Prova de PIN (PIN Proof) sobre o PIN que tem em cache (ou, para um Certificado A1, sobre o verificador do PIN do Certificado A1), e o Servidor decide se correspondeu. Os Servidores 1.13.0 a 1.14.1 têm a janela 4–5.

MáquinaProtocoloCom o Servidor 1.13.0 a 1.14.1
Workstation 1.5.05Totalmente suportada.
Workstation 1.4.x4Conecta, é licenciada, assina para as sessões já vinculadas a ela e pode receber a oferta de uma versão. Ela nunca recebe desafio de PIN nem pedido de PIN, então, para a criação de sessão, conta como offline: um titular cujas máquinas estão todas no protocolo 4 recebe 422 WORKSTATION_OFFLINE, e o Servidor registra um Warning citando a máquina cada vez que a deixa de lado.
Workstation 1.0.x a 1.3.02 ou 3Recusada no handshake, com Atualização necessária na linha dela na frota e na Trilha de Auditoria. Ela também não pode receber oferta de versão: atualize-a manualmente ou por Política de Grupo.

Essa atualização não seguiu "primeiro o Servidor, a frota dentro de uma versão". Uma máquina no protocolo 4 não atende novas sessões até ser atualizada, então o Servidor e a frota foram atualizados juntos: o upload do Workstation 1.5.0 foi feito na tela Versões da Estação de Trabalho como parte da atualização do Servidor, e a versão foi oferecida na hora. Uma máquina no protocolo 5 não consegue se conectar a um Servidor anterior ao 1.13.0 (janela 3–4).

O que muda para os integradores: nada. O PIN continua chegando em POST /v1/sessions e não vai além do Servidor. INVALID_PIN agora significa que todas as candidatas deram uma prova e nenhuma conferiu com o PIN enviado.

Atualizar um Servidor e sua frota para o protocolo 4​

O protocolo 4 (Servidor 1.9.0, Workstation 1.4.0) é a versão em que o Servidor diz a uma máquina qual Versão da Estação de Trabalho lhe é oferecida, então as atualizações entregues pelo Servidor precisam dele nas duas pontas. Em todo handshake, uma máquina no protocolo 4 ou posterior informa ao Servidor se a Política de Grupo desligou as atualizações entregues pelo Servidor, o Publisher Pin com que o Service dela foi gerado e como terminou a última atualização. O Servidor mostra as três informações na linha da máquina e grava workstation.update-installed, workstation.update-failed ou workstation.update-refused na Trilha de Auditoria quando o resultado informado muda.

Uma oferta só alcança uma máquina Admitida abaixo da versão, cujo Publisher Pin liste o assinante da versão e cuja política deixe as atualizações ligadas. Oferecer de novo a uma máquina a versão que ela já tem é a forma de tentar outra vez depois de uma instalação que falhou, porque uma máquina nunca tenta de novo sozinha. Uma versão oferecida a qualquer máquina não pode ser excluída até as ofertas serem retiradas. As telas estão descritas em Console administrativo.

Downloads de Versões da Estação de Trabalho​

Como o Servidor entrega a uma máquina a Versão da Estação de Trabalho que lhe foi oferecida. Uma versão oferecida a todas as máquinas são até 500 máquinas × cerca de 100 MB vindos de um único Servidor, então a única chave daqui serve para evitar um estouro de downloads simultâneos. Uma implantação padrão não a define.

Uma máquina baixa de GET /workstations/releases/{version}. Toda requisição, tanto uma faixa retomada quanto a primeira, traz uma asserção nova assinada pela Chave da Estação de Trabalho e só é atendida enquanto o Servidor oferece aquela versão àquela máquina, então retirar uma oferta interrompe um download na requisição seguinte. Toda recusa responde o mesmo 401; o log do Servidor diz qual verificação falhou (A Workstation Release download was refused). Os downloads ficam fora do throttling global e não gravam linha própria na Trilha de Auditoria; a trilha registra o que cada máquina fez depois com o arquivo.

Um download é servido da cópia em /tmp/trustbridge-releases, recriada a partir do banco de dados quando falta, ou lida direto do banco onde esse diretório não pode ser gravado, o que o Servidor registra uma vez em Warning.

environment:
WorkstationReleases__MaxConcurrentDownloads: "20"

WorkstationReleases:MaxConcurrentDownloads​

Padrão 20 · Override pelo Administrador não · Exige reinício sim

Quantos downloads de versões o Servidor envia ao mesmo tempo. Um download ocupa a vaga enquanto a requisição dele durar. Um acima do limite recebe 503 com Retry-After, nunca o 429 SERVER_BUSY do contrato, com uma espera sorteada de novo entre 30 e 90 segundos, para que máquinas recusadas juntas não voltem juntas. Cada máquina também espera um atraso aleatório de até dez minutos antes de começar, o que espalha a maior parte de uma distribuição antes de este limite ser atingido.

Aumente-o para um Servidor com um link rápido cuja frota deva se atualizar mais cedo; reduza-o onde o link é compartilhado com tráfego de assinatura que não pode esperar. Zero ou negativo recusa a inicialização.

Relatórios das Estações de Trabalho​

O que o Servidor guarda do Relatório da Estação de Trabalho que cada máquina envia por conta própria (Servidor 1.20.0 e posteriores; o Workstation 1.8.0 é a primeira release que envia um). Cada informação de um relatório substitui a anterior, então só os erros precisam de retenção: um grupo por máquina, origem, categoria de log e modelo de mensagem, com uma contagem acumulada, mantido até a máquina passar um tempo sem informá-lo. Eles nunca são gravados na Trilha de Auditoria. Uma implantação padrão não a define.

O Servidor também guarda o console de cada máquina (Servidor 1.23.0, de máquinas no Workstation 1.10.0 ou posterior): a Conta no console, se a sessão do console está bloqueada, se um Tray App roda ali e a versão dele, e quantas outras sessões têm um, como o último relatório disse. Ele não precisa de retenção: é mantido para uma máquina desconectada ou revogada, vai embora com uma máquina removida, é apagado por um relatório que diz que o envio está desligado e nunca é gravado na Trilha de Auditoria.

environment:
WorkstationReports__ErrorRetentionDays: "30"

WorkstationReports:ErrorRetentionDays​

Padrão 30 · Override pelo Administrador não · Exige reinício sim

Por quantos dias um grupo de erros de uma máquina é mantido depois que a máquina deixou de informá-lo. Uma varredura diária exclui os grupos a que nenhum relatório acrescentou nada há mais tempo que isso, pelo relógio deste Servidor, de modo que uma máquina com o relógio errado não perde os grupos antes da hora nem os mantém para sempre; um grupo que a máquina informa de novo é mantido, e a contagem continua. A contagem das linhas que uma máquina registrou além dos 100 tipos que um relatório lista segue a mesma regra. Uma máquina removida leva os grupos dela junto, qualquer que seja a idade deles. O chip N tipos de erro (24h) da página da frota conta só o último dia, qualquer que seja este valor, então reduzi-lo encurta o histórico do painel de detalhes e não muda nenhum chip.

Abaixo de 1, recusa a inicialização: a passagem seguinte excluiria todos os grupos de erros que a frota informou.

O Cofre de Certificados​

environment:
Vault__Enabled: "true"
Vault__RevalidationInterval: "01:00:00"

Vault:Enabled​

Padrão false · Override pelo Administrador não, de propósito · Exige reinício sim

Se o Cofre de Certificados existe neste Servidor, isto é, se ele pode guardar uma chave privada própria. Desligado por padrão porque esse nível torna condicional a premissa fundadora da plataforma; o operador decide ativá-lo. Uma linha salva no banco de dados com esta chave é ignorada, pelo mesmo motivo de Admin:SecondFactor:Required. Ligá-lo dá à licença do PKI SDK, que toda implantação já tem, uma segunda função (ler os Certificados do Cofre do próprio Servidor) e traz junto a trava do cofre. Desligá-lo não exclui nada: as linhas permanecem, a revalidação para, e os caminhos que as leriam respondem que este Servidor não tem chaveiro.

Vault:RevalidationInterval​

Padrão 1 h · Override pelo Administrador não · Exige reinício sim

A frequência com que o Servidor verifica de novo o veredito do que o cofre guarda. Não é validada na inicialização: um valor não positivo é informado no nível Critical, e o worker não roda.

Validação de certificados e licença do PKI SDK​

O mesmo nome de seção que o Workstation Service lê, com duas chaves que só fazem sentido lá. A licença é obrigatória e carregada em toda inicialização, com ou sem cofre, porque é a licença com que toda a frota funciona. Só uma implantação com o cofre ligado resolve o conjunto de âncoras; os timeouts e a janela de tolerância são validados em toda inicialização, de qualquer forma.

environment:
Certificates__Validation__License: ${PKI_LICENSE}
Certificates__Validation__UseIcpBrasil: "true"
Certificates__Validation__UseMachineRootStore: "false"
Certificates__Validation__UseLacunaTestPki: "false"
Certificates__Validation__RevocationGraceWindow: "1.00:00:00"
Certificates__Validation__RevocationTimeout: "00:00:05"
Certificates__Validation__CheckTimeout: "00:00:30"

Certificates:Validation:License​

Padrão não definido · Override pelo Administrador não · Exige reinício sim

Obrigatória em toda implantação, com ou sem Cofre de Certificados. O LacunaPkiLicense.config inteiro que a Lacuna emite, codificado em base64 numa única linha, e não um caminho. A imagem não traz licença, então uma renovação é uma alteração de configuração e um reinício, e não um novo build.

É a licença da frota, além da do Servidor. O Servidor entrega o valor, exatamente como está configurado, a toda estação de trabalho Admitida na resposta ao handshake dela; é assim que um Workstation Service instalado é licenciado, e não há licença a definir numa máquina. A máquina a guarda só em memória e a recebe de novo a cada conexão, então reiniciar o Servidor alcança a frota inteira: toda máquina conectada se reconecta e aplica o valor, e uma máquina que estava offline o recebe quando se conectar de novo. Uma máquina Pendente não recebe nada.

base64 -w0 LacunaPkiLicense.config
[Convert]::ToBase64String([IO.File]::ReadAllBytes("LacunaPkiLicense.config"))
EstadoO que acontece
Ausente (não definida, vazia ou em branco)O Servidor recusa a inicialização, citando esta chave. Verificado antes da etapa do schema, então um Servidor que vai recusar não migra o banco de dados antes.
Recusada (vencida, corrompida, não é base64, não é uma licença)O Servidor inicia e registra uma linha Critical citando esta configuração, com uma linha Error dizendo o motivo quando ele é conhecido. Toda página administrativa mostra um banner dizendo que nem a frota nem o cofre conseguem assinar até a licença ser renovada. O valor continua sendo entregue à frota, e cada máquina que o recusa avisa em Critical. Com o cofre ligado, todos os Certificados do Cofre informam UNTRUSTED e as importações são recusadas de imediato.
CarregadaUma linha na inicialização dizendo que o SDK está licenciado e pronto.

Ela vence, e nada avisa antes dessa data. O primeiro aviso é a linha Critical e o banner, e a essa altura nada assina, nem no cofre nem em nenhuma máquina. Renová-la é substituir este valor e reiniciar o Servidor; não há caminho em tempo de execução, e um Administrador não pode sobrescrevê-la pelo console. Coloque o vencimento dela no calendário que acompanha as renovações de certificados. O SDK só lê uma licença a partir de um arquivo, então o valor é gravado em /tmp/trustbridge-pki e excluído na mesma chamada; um sistema de arquivos somente leitura sem um /tmp gravável não consegue carregar a licença.

As fontes de âncoras​

ChavePadrãoSignificado
Certificates:Validation:UseIcpBrasiltrueConfiar nas raízes da ICP-Brasil que o PKI SDK traz: o conjunto de âncoras de produção, embutido, sem download. Desligar é uma decisão de confiança.
Certificates:Validation:UseMachineRootStorefalseConfiar também no repositório de raízes da própria máquina. No Servidor, um container Linux, não faz nada; é uma opção da estação de trabalho.
Certificates:Validation:UseLacunaTestPkifalseConfiar também na PKI de teste da Lacuna. Somente para desenvolvimento: a Lacuna publica as chaves privadas desses certificados de exemplo. Um Servidor com esta opção ligada registra Critical na inicialização e mostra um banner de aviso em todas as páginas administrativas.
Certificates:Validation:UseServerTrustedCastrueUma opção da estação de trabalho. Inerte no Servidor.
Certificates:Validation:TrustedRootPathsvazioNão é considerada no Servidor. Um Servidor que a encontra definida inicia mesmo assim e registra uma linha Critical citando a chave e a página administrativa que a substituiu. Em vez dela, adicione uma Autoridade Certificadora Confiável em /admin/trusted-cas.

Duas linhas Critical descrevem um conjunto de âncoras que não ancora nada: nenhuma âncora, e âncoras que são só intermediárias, sem raiz autoassinada, de modo que nenhuma cadeia consegue terminar. As duas situações tornam todo certificado UNTRUSTED.

Os limites de revogação​

ChavePadrãoSignificado
Certificates:Validation:RevocationGraceWindow24 h (1.00:00:00)Por quanto tempo a última verificação de revogação bem-sucedida mantém um certificado ACTIVE enquanto a AC dele está inacessível; passado esse prazo, o certificado vira STALE. Esta é a decisão de confiança: exatamente por quanto tempo um certificado continua assinando depois que a AC parou de responder, revogado ou não. Zero é válido e é o mais rigoroso; um valor negativo recusa a inicialização.
Certificates:Validation:RevocationTimeout5 sQuanto tempo um download de LCR ou uma busca de emissor pode levar antes de a AC ser considerada inacessível. Também limita cada busca do percurso AIA da descoberta de Autoridades Certificadoras Confiáveis. Um valor não positivo recusa a inicialização.
Certificates:Validation:CheckTimeout30 sO limite externo de toda a verificação de um certificado, incluindo o fallback para OCSP do SDK, que não tem limite próprio. Zero espera indefinidamente e não é recusado.

Configurações que não são chaves de appsettings​

ConfiguraçãoPertence aOnde
ASPNETCORE_ENVIRONMENTO frameworkNão definida nos dois cenários, e não definida significa Production, o que mantém o appsettings.Development.json inerte.
ASPNETCORE_URLSKestrelhttps://+:8443 no Docker, somente HTTPS, ou https://+:8443;http://localhost:8080 para fazer Assinaturas de teste (veja A Assinatura de teste). http://+:8443 no Docker atrás de um proxy reverso que termina o TLS, sem as configurações Kestrel__Certificates__*. Não definida no App Service.
Kestrel__Certificates__Default__Path / __PasswordKestrelO certificado TLS do próprio Servidor no Docker. Nada a definir no App Service.
WEBSITES_PORTApp Service8080.
WEBSITES_CONTAINER_START_TIME_LIMITApp Service1800, para que uma migração longa não seja encerrada e reiniciada em loop.
ASPNETCORE_FORWARDEDHEADERS_ENABLEDO frameworktrue no App Service, ou toda linha de auditoria registra o front end da plataforma em vez de quem fez a chamada. Ela confia em quem se conectar, então um proxy que você opera é citado em ForwardedHeaders:TrustedProxies; definir as duas recusa a inicialização.
APPLICATIONINSIGHTS_CONNECTION_STRINGApp ServiceLida quando Logging:ApplicationInsights:ConnectionString não está definida.
TMPDIRO processoMove os três diretórios temporários (trustbridge-pki, trustbridge-logs, trustbridge-releases). De propósito, não existe configuração do TrustBridge para isso.
Ver em Markdown