Skip to content

About

TEC.Vault: acesso a cofres de segredos (HashiCorp, Infisical, Azure Key Vault, AWS, Google) para .NET 10

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

19 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TEC.Vault

🔐 TEC.Vault

Segredos, chaves e certificados com uma única API: troque de cofre sem mudar o código, criptografe sem expor chaves e audite cada acesso sem registrar valores.

Azure Key Vault · HashiCorp Vault/OpenBao · AWS Secrets Manager · Google Secret Manager · Infisical · Provedor Encadeado (Fallback) · Segredos sincronizados (ESO, CSI, Vault Agent, Bitwarden) · Em memória · .NET 10 · Native AOT

CI .NET Native AOT Versão Licença: Apache 2.0

📥 Instalação · 🚀 Início rápido · 📚 Documentação · 📝 Changelog · ⚙️ CI/CD


📑 Sumário


✨ Por que usar

Sem o TEC.Vault Com o TEC.Vault
Cada aplicação usa o SDK do cofre direto, com erro, retentativa e log diferentes Uma API única (ISecretReader, IKeyCryptography, ICertificateReader...) com o mesmo comportamento em qualquer cofre
Trocar de cofre exige reescrever o acesso a segredos Trocar de cofre é trocar o appsettings.{Ambiente}.json ("Vault": { "Provider": "HashiCorpVault" }), sem recompilar
Exceções do SDK chegam ao cliente com URL do cofre e identidade Todo método retorna Result/Result<T> com códigos de VaultErrors; falhas de infraestrutura saem ocultas (HTTP 502)
Client secret no appsettings para abrir o cofre Autenticação sem segredo (identidade gerenciada, federada, Kubernetes); credencial de desenvolvedor só em Development
Valores vazando em log por interpolação ou pelo SDK Valores nunca em log, ToString() mascarado, nomes recusados só como tamanho + HMAC
Chave privada baixada para assinar ou cifrar A chave fica no cofre: cifra, wrap e assinatura no próprio cofre; envelope para dados grandes
Cofre real até para rodar localmente Provedor em memória completo (criptografia real), bloqueado fora de Development
  • ✅ Seguro por padrão: entrada validada antes de chamar o cofre, limites contra DoS (listagens, respostas, arquivos), auditoria de escritas e downloads de chave privada.
  • ✅ Escolha por configuração: provedor por família (segredos, chaves, certificados), leitura estrita e compatível com AOT; erro de digitação derruba a subida, não a primeira requisição.
  • ✅ Completo: CRUD, versões, lixeira, backup, geração e rotação de segredos, envelope, certificados (criação, importação PFX/PEM, PKI), IConfiguration com recarga, cache com proteção contra stampede, health check e telemetria.
  • ✅ Extensível: VaultProviderBase e a base HTTP sem SDK, com testes de contrato prontos para um provedor novo.

📦 Pacotes

Pacote Para que serve Quando instalar Depende de
TEC.Vault Interfaces, modelos, VaultErrors, validação, auditoria, métricas, cache, IConfiguration, health check, envelope, provedor encadeado, escolha por configuração e base para provedores Vem com qualquer provedor; sozinho só para escrever um provedor ou uma biblioteca que recebe ISecretReader TEC.Core, Polly.Core, Microsoft.Extensions.* (sem SDK de nuvem)
TEC.Vault.AzureKeyVault Azure Key Vault: segredos, chaves e certificados, autenticação sem segredo Aplicações no Azure TEC.Vault, Azure.Identity, Azure.Security.KeyVault.*
TEC.Vault.AwsSecretsManager AWS Secrets Manager: leitura, gravação, tags e versionamento nativo HTTP com SigV4 (sem SDK pesado, 100% Native AOT); credenciais por IRSA, container do ECS/EKS, IMDSv2 ou variáveis, renovadas antes de expirar Aplicações na AWS (EKS, ECS, EC2) ou multi-cloud TEC.Vault (HTTP SigV4, sem SDK)
TEC.Vault.GoogleSecretManager Google Cloud Secret Manager: leitura, gravação, exclusão, labels, habilitar/desabilitar versões e metadados via API REST v1 nativa (Service Account JSON ou Metadata Server GKE/Cloud Run, 100% Native AOT) Aplicações no Google Cloud (GKE, Cloud Run, GCE) ou multi-cloud TEC.Vault (HTTP REST v1, sem SDK)
TEC.Vault.HashiCorpVault HashiCorp Vault e OpenBao: KV v2 com lixeira, Transit, certificados com PKI; login Kubernetes, JWT, AppRole ou token HashiCorp Vault/OpenBao (on-premises, Kubernetes, HCP) TEC.Vault (HTTP, sem SDK)
TEC.Vault.Infisical Infisical (nuvem ou self-hosted): leitura e gravação de segredos Aplicações que leem e gravam no Infisical pela API TEC.Vault (HTTP, sem SDK)
TEC.Vault.Synced Segredos já entregues por um agente: pasta montada, variáveis de ambiente, arquivo JSON/.env (só leitura) External Secrets, CSI driver, Vault Agent, infisical run, bws run (Bitwarden) TEC.Vault
TEC.Vault.InMemory Cofre em memória com o mesmo comportamento dos reais Desenvolvimento local e testes (bloqueado fora de Development) TEC.Vault

Os oito pacotes saem sempre com a mesma versão e trazem lib/net10.0, a documentação XML em português e um README próprio.

🧬 Ecossistema TEC

flowchart BT
    Core["🧰 TEC.Core<br/><sub>Result, erros, utilitários</sub>"]
    Vault["🔐 TEC.Vault<br/><sub>segredos, chaves, certificados</sub>"]
    Cqrs["🧭 TEC.Cqrs<br/><sub>commands, queries, pipeline</sub>"]
    Sec["🛡️ TEC.Security<br/><sub>autenticação, autorização</sub>"]
    Obs["📡 TEC.Observability<br/><sub>traces, métricas, logs</sub>"]
    Orm["🗄️ TEC.ORM<br/><sub>persistência</sub>"]
    Vault --> Core
    Cqrs --> Core
    Sec --> Core
    Sec --> Vault
    Orm --> Core
    Orm --> Cqrs
    Orm --> Vault
    classDef atual fill:#512BD4,color:#fff,stroke:#512BD4,stroke-width:2px
    class Vault atual
Loading

O TEC.Vault guarda tudo o que é sensível no ecossistema e depende só do TEC.Core: as outras bibliotecas pedem segredos, chaves e certificados a ele em vez de lê-los da configuração.

Componente Relação com o TEC.Vault
🧰 TEC.Core Dependência: Result/Error, Guard, gerador seguro de segredos, AES-GCM do envelope, HMAC, BoundedFileReader, SensitiveDataMasker
🛡️ TEC.Security Consumidor: lê o certificado, a chave ou o segredo da aplicação por ICertificateReader, IKeyCryptography ou ISecretReader
🗄️ TEC.ORM Consumidor: lê a string de conexão do cofre por ISecretReader
🧭 TEC.Cqrs Independente; handlers podem injetar ISecretReader/IKeyCryptography e propagar o Result
📡 TEC.Observability Sem dependência de pacote: assina o ActivitySource e o Meter TEC.Vault e expõe o health check

📥 Instalação

Os pacotes estão no GitHub Packages da organização tudoemcodigo, que sempre exige autenticação (mesmo para leitura). Crie um PAT classic com o escopo read:packages, registre a origem com o nome tec-interno e instale só os provedores que a aplicação pode usar (cada um traz o TEC.Vault junto):

dotnet nuget add source https://nuget.pkg.github.com/tudoemcodigo/index.json -n tec-interno -u <usuario> -p <PAT>

dotnet add package TEC.Vault.AzureKeyVault --version 0.0.1
dotnet add package TEC.Vault.AwsSecretsManager --version 0.0.1
dotnet add package TEC.Vault.GoogleSecretManager --version 0.0.1
dotnet add package TEC.Vault.HashiCorpVault --version 0.0.1
dotnet add package TEC.Vault.Infisical --version 0.0.1
dotnet add package TEC.Vault.Synced --version 0.0.1
dotnet add package TEC.Vault.InMemory --version 0.0.1

Important

Versão atual: 0.0.1. Para evitar dependency confusion, mapeie TEC.* só para a origem tec-interno no nuget.config da aplicação (packageSourceMapping).

🚀 Início rápido

1. Escolha o cofre de cada ambiente no appsettings (endereço não é segredo; nenhum segredo vai aqui):

// appsettings.Development.json: cofre em memória, sem infraestrutura
{ "Vault": { "Provider": "InMemory", "InMemory": { "InitialSecrets": { "parceiro-api-token": "token-local" } } } }
// appsettings.Production.json: Azure Key Vault com identidade gerenciada
{ "Vault": { "Provider": "AzureKeyVault", "AzureKeyVault": { "VaultUri": "https://<nome-do-cofre>.vault.azure.net/" } } }

2. Registre o cofre e o health check, declarando os provedores disponíveis:

using TEC.Vault.AzureKeyVault;
using TEC.Vault.DependencyInjection;
using TEC.Vault.HealthChecks;
using TEC.Vault.InMemory;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddTecVault(builder.Configuration.GetSection("Vault"), providers => providers
    .AddInMemory()          // escolhido em Development
    .AddAzureKeyVault());   // escolhido em produção

builder.Services.AddHealthChecks().AddTecVault();   // tags "ready" e "vault"

var app = builder.Build();
app.MapHealthChecks("/health/ready");
app.Run();

3. Injete só a interface de que precisa e trate o Result:

using TEC.Core.Common.Results;
using TEC.Vault.Abstractions;

public sealed class PartnerClient(ISecretReader vault)   // só lê: injete o leitor
{
    public async Task<Result> CallAsync(CancellationToken cancellationToken)
    {
        var token = await vault.GetSecretAsync("parceiro-api-token", cancellationToken: cancellationToken);
        if (token.IsFailure)
            return token.ToFailure();   // NotFound, ExternalService... já padronizados

        // use token.Value.Value; nunca registre em log (ToString() já mascara)
        return Result.Success();
    }
}

Provedor desconhecido, chave digitada errado ou endereço inválido derrubam a subida com InvalidOperationException (citando o caminho da chave). Registro em código (AddTecVault(vault => vault.UseAzureKeyVault(...))), outros provedores e todas as opções: 📚 documentação.

🧭 O que tem dentro

flowchart LR
    APP["Aplicação"] --> I["Interfaces<br/>ISecretReader · IKeyCryptography · ICertificateReader ..."]
    I -. opcional .-> C["Cache de segredos"]
    I --> B["VaultProviderBase<br/>validação · Result · auditoria · métricas"]
    C --> B
    SEL["Vault:Provider<br/>catálogo de provedores"] -. escolhe .-> B
    B --> AZ["AzureKeyVault"] --> KV[("Azure Key Vault")]
    B --> AWS["AwsSecretsManager"] --> ASM[("AWS Secrets Manager")]
    B --> GCP["GoogleSecretManager"] --> GSM[("Google Secret Manager")]
    B --> HC["HashiCorpVault"] --> HV[("HashiCorp Vault<br/>OpenBao")]
    B --> INF["Infisical"] --> IS[("Infisical")]
    B --> CHN["ChainedSecrets"] --> FB["Fallback em Camadas"]
    B --> SYN["Synced / Variáveis"]
    AGT["Agente externo / Variáveis<br/>ESO · CSI · Vault Agent · bws · env"] --> SYN
    B --> MEM["InMemory"]
Loading
Família Leitura Gestão Extras Opcionais
🔑 Segredos ISecretReader ISecretStore GenerateSecretAsync, RotateSecretAsync ISecretRecycleBin, ISecretBackup
🔐 Chaves IKeyReader IKeyStore IKeyCryptography, EncryptEnvelopeAsync IKeyRecycleBin, IKeyBackup
📜 Certificados ICertificateReader ICertificateStore Importação PFX/PEM, emissão por PKI ICertificateRecycleBin, ICertificateBackup
💓 Saúde IVaultHealthProbe — AddHealthChecks().AddTecVault() —
Provedor Segredos Chaves Certificados Lixeira Backup
Azure Key Vault ✅ ✅ ✅ ✅ ✅
HashiCorp Vault / OpenBao ✅ KV v2 ✅ Transit ✅ KV + PKI ✅ —
AWS Secrets Manager ✅ — — — —
Google Secret Manager ✅ — — — —
Infisical ✅ — — — —
Encadeado (Chained) ✅ fallback — — — —
Synced (Directory, EnvironmentVariables, SecretsFile) ✅ só leitura — — — —
Em memória ✅ ✅ ✅ ✅ ✅

AddTecVault registra cada interface que o provedor implementa apontando para a mesma instância (singleton, thread-safe); pedir uma interface que o provedor não oferece falha na resolução do DI, não em tempo de execução.

📚 Documentação

Arquivo O que responde
🔑 Segredos Como ler, gravar, versionar, gerar, rotacionar, recuperar e fazer backup de segredos
🔐 Chaves Como criar e rotacionar chaves, cifrar, assinar e usar criptografia envelope
📜 Certificados Como criar, importar (PFX/PEM), baixar e gerenciar certificados
🧩 Injeção de dependências O que AddTecVault registra, VaultBuilder, VaultStores
⚙️ Escolha do cofre pela configuração Como escolher o provedor por ambiente no appsettings e todas as chaves Vault:*
🧾 Segredos no IConfiguration Como carregar segredos como configuração, com recarga incremental
💾 Cache e health check Como ligar o cache de segredos e o health check
🌐 Azure Key Vault Opções, autenticação, RBAC e limites do provedor Azure
🏛️ HashiCorp Vault KV v2, Transit, PKI, login, política de menor privilégio, OpenBao
🟣 Infisical Universal Auth, Kubernetes Auth, versões, tags e permissões
☁️ AWS Secrets Manager SigV4 nativo, JSON protocol 1.1 sem SDK, IRSA, container do ECS/EKS, IMDSv2 e chaves de variáveis, erros da AWS
🔷 Google Secret Manager API REST v1 nativa, token em variável, Service Account JSON com token_uri conferido, Google Metadata Server (GKE, Cloud Run), labels
🔗 Provedor Encadeado Fallback ordenado multicamadas (ex.: variáveis de ambiente para cofre remoto)
🌐 Segredos em Variáveis de Ambiente Guia dedicado para segredos em variáveis de ambiente, normalização de nomes, isolamento de escopo e fallback
📂 Synced Pasta, variáveis e arquivo entregues por agentes, com receitas (ESO, CSI, Vault Agent, bws run)
🧠 Em memória Cofre local para desenvolvimento e testes, e a trava de ambiente
🧱 Novo provedor Como escrever um provedor (VaultProviderBase, base HTTP, catálogo, testes de contrato)
📈 Observabilidade Spans, métricas (tec.vault.*; os nomes vault.* estão obsoletos) e eventos de log (EventId 7000–7999)
🔁 Resiliência Retentativa e circuit breaker: o que abre o circuito, opções e telemetria
🏛️ ADRs Registros de Decisões Arquiteturais
❌ Erros Códigos de VaultErrors, HTTP, conversão por provedor e exceções de configuração
🛡️ Segurança Modelo de ameaças, controles, limites, riscos residuais e checklist
🧪 Testes Categorias, como rodar local, integração e carga, variáveis TEC_TESTES_*/TEC_CARGA_*
💻 Desenvolvimento local Como compilar (feed tec-interno por padrão, repositórios vizinhos sob demanda) e regenerar lock files
🧰 Samples Escolha do cofre por ambiente e gerador de carga
⚙️ CI/CD Workflows, gatilhos, Variables e como publicar

⚡ Compatibilidade

Item Suporte
.NET net10.0 (LTS)
Native AOT / trimming ✅ IsAotCompatible em todos os pacotes; sem binding nem JSON por reflexão (configuração lida com VaultSettings, JSON com source generator/Utf8JsonWriter) ¹
Sem ICU (InvariantGlobalization) ✅ testado no CI
HTTP HashiCorp Vault, Infisical, AWS e Google usam VaultHttpClient com SocketsHttpHandler de vida longa e renovação de conexões (sem IHttpClientFactory), retentativa, tempo limite também na leitura do corpo e teto de resposta (resiliência)
Cofres testados de verdade HashiCorp Vault em container (KV v2, Transit, PKI) a cada PR; Key Vault de testes na main
Sistemas Windows, Linux e macOS; Kubernetes (service account, volumes montados)

¹ O Azure.Core gera avisos de trimming só no decodificador de PKCS#8 EC, usado por credenciais com certificado EC em PEM; ManagedIdentity, WorkloadIdentity e Developer não passam por ele.

🛡️ Segurança

Zero Trust: nome, versão, tags e respostas do cofre são tratados como não confiáveis. Endereços HTTPS validados (o token nunca vai a outro servidor), autenticação sem segredo, entrada validada antes da chamada, listagens limitadas (MaxListItems, padrão 10.000), respostas e arquivos de credencial com teto, valores nunca em log e erros de infraestrutura ocultos do cliente, em todos os provedores. A fonte de IConfiguration exige um prefixo por aplicação (Prefix), para que um segredo alheio não sobrescreva uma chave da configuração.

Caution

Conceda à identidade da aplicação só o papel mínimo (ex.: Key Vault Secrets User para apenas ler) e ative proteção contra purge no cofre de produção. Modelo de ameaças, permissões por provedor e checklist: docs/seguranca.md. Vulnerabilidades: não abra issue pública; escreva para roberto@roberto.inf.br.

🧪 Testes

dotnet test --project TEC.Vault.Tests -c Release                         # unitários + integração (pula sem ambiente)
dotnet test --project TEC.Vault.LoadTests -c Release --treenode-filter "/*/*/*/*[Category=Carga-CI]"   # carga rápida

Para a integração com HashiCorp Vault, suba um container descartável na porta 18200 e prepare-o com .github/scripts/vault-dev.sh (passo a passo em docs/testes.md).

Testes unitários em TEC.Vault.Tests (TUnit, com testes de contrato, fuzzing e vazamento sob carga), 37 de integração ([Category=Integracao]: HashiCorp Vault real em container e Key Vault de testes, pulados com motivo sem ambiente), 7 de carga rápida (Carga-CI) e 13 pesados (Carga-Pesada), estes de carga só sob demanda no performance.yml (manual: tempo em runner compartilhado é ruidoso e não bloqueia PR nem versão). Detalhes em docs/testes.md.

🤝 Contribuição

Branch a partir da main → código e testes (inclusive entradas inválidas) → dotnet test (com e sem ICU) → CHANGELOG e docs/ atualizados → pull request com o check ci / ci-ok verde. Como compilar (credencial do feed tec-interno, modo local com -p:TecUseLocalProjects=true): docs/desenvolvimento.md.

🏷️ Versionamento

SemVer, uma versão para os oito pacotes (Directory.Build.props). Enquanto for 0.x, mudanças incompatíveis podem ocorrer em versões MINOR; um membro novo em interface conta como incompatível (quebra provedores de terceiros). Cada merge na main publica a prévia <Version>-preview.N; versões estáveis e -rc.N saem só pelo workflow Publicar versão (CI/CD).

📄 Licença

Apache 2.0 — consulte NOTICE para informações de atribuição. Criado e mantido por Roberto Oliveira, equipe Tudo em Código · github.com/tudoemcodigo

About

TEC.Vault: acesso a cofres de segredos (HashiCorp, Infisical, Azure Key Vault, AWS, Google) para .NET 10

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages