[{"data":1,"prerenderedAt":1062},["ShallowReactive",2],{"doc-\u002Fdocs\u002Fseguranca\u002Fsecrets":3,"docs-all":992},{"id":4,"title":5,"body":6,"category":975,"description":976,"draft":977,"extension":978,"icon":979,"lastReviewed":980,"meta":981,"navigation":75,"order":41,"path":982,"prerequisites":983,"readingTime":984,"seo":985,"stem":986,"tags":987,"__hash__":991},"docs_pt\u002Fdocs\u002Fseguranca\u002Fsecrets.md","Gerenciamento de segredos",{"type":7,"value":8,"toc":962},"minimark",[9,13,16,19,24,27,138,141,145,205,211,225,229,232,235,242,257,260,264,267,325,328,331,385,388,392,395,467,470,488,491,511,514,518,521,595,604,608,611,636,649,679,682,686,689,807,810,817,821,824,865,872,875,879,882,936,940,958],[10,11,12],"p",{},"Senha de banco, chave de API, token OAuth, credencial de provedor. Tudo isso é segredo e nada disso pode estar no spec do job.",[10,14,15],{},"Por dois motivos. Primeiro, specs costumam ser versionados em algum repositório. Qualquer pessoa com acesso de leitura ao repositório passa a ter acesso ao segredo. Segundo, specs trafegam em logs, em terminais compartilhados, em screenshots de revisão. Cada um desses pontos é um vazamento esperando para acontecer.",[10,17,18],{},"O HeroCtl traz um cofre de segredos integrado. Você não monta nada por fora.",[20,21,23],"h2",{"id":22},"criando-um-segredo","Criando um segredo",[10,25,26],{},"Pela CLI, três formas:",[28,29,34],"pre",{"className":30,"code":31,"language":32,"meta":33,"style":33},"language-bash shiki shiki-themes github-dark-default","# valor literal direto na linha de comando\nheroctl secret create db_password --from-literal=\"s3nh4-l0nga-e-aleatoria\"\n\n# de um arquivo\nheroctl secret create tls_key --from-file=.\u002Fprivkey.pem\n\n# stdin (não fica no histórico do shell)\necho -n \"valor-secreto\" | heroctl secret create api_token --from-stdin\n","bash","",[35,36,37,46,70,77,83,98,103,109],"code",{"__ignoreMap":33},[38,39,42],"span",{"class":40,"line":41},"line",1,[38,43,45],{"class":44},"sH3jZ","# valor literal direto na linha de comando\n",[38,47,49,53,57,60,63,67],{"class":40,"line":48},2,[38,50,52],{"class":51},"sQhOw","heroctl",[38,54,56],{"class":55},"s9uIt"," secret",[38,58,59],{"class":55}," create",[38,61,62],{"class":55}," db_password",[38,64,66],{"class":65},"sFSAA"," --from-literal=",[38,68,69],{"class":55},"\"s3nh4-l0nga-e-aleatoria\"\n",[38,71,73],{"class":40,"line":72},3,[38,74,76],{"emptyLinePlaceholder":75},true,"\n",[38,78,80],{"class":40,"line":79},4,[38,81,82],{"class":44},"# de um arquivo\n",[38,84,86,88,90,92,95],{"class":40,"line":85},5,[38,87,52],{"class":51},[38,89,56],{"class":55},[38,91,59],{"class":55},[38,93,94],{"class":55}," tls_key",[38,96,97],{"class":65}," --from-file=.\u002Fprivkey.pem\n",[38,99,101],{"class":40,"line":100},6,[38,102,76],{"emptyLinePlaceholder":75},[38,104,106],{"class":40,"line":105},7,[38,107,108],{"class":44},"# stdin (não fica no histórico do shell)\n",[38,110,112,115,118,121,125,128,130,132,135],{"class":40,"line":111},8,[38,113,114],{"class":65},"echo",[38,116,117],{"class":65}," -n",[38,119,120],{"class":55}," \"valor-secreto\"",[38,122,124],{"class":123},"suJrU"," |",[38,126,127],{"class":51}," heroctl",[38,129,56],{"class":55},[38,131,59],{"class":55},[38,133,134],{"class":55}," api_token",[38,136,137],{"class":65}," --from-stdin\n",[10,139,140],{},"Pelo painel web, há um formulário equivalente.",[20,142,144],{"id":143},"listando-e-inspecionando","Listando e inspecionando",[28,146,148],{"className":30,"code":147,"language":32,"meta":33,"style":33},"# lista todos os segredos visíveis pelo seu token\nheroctl secret list\n\n# mostra metadados (versão, autor, data de criação) — nunca o valor\nheroctl secret describe db_password\n\n# mostra o valor (exige permissão explícita)\nheroctl secret get db_password\n",[35,149,150,155,164,168,173,185,189,194],{"__ignoreMap":33},[38,151,152],{"class":40,"line":41},[38,153,154],{"class":44},"# lista todos os segredos visíveis pelo seu token\n",[38,156,157,159,161],{"class":40,"line":48},[38,158,52],{"class":51},[38,160,56],{"class":55},[38,162,163],{"class":55}," list\n",[38,165,166],{"class":40,"line":72},[38,167,76],{"emptyLinePlaceholder":75},[38,169,170],{"class":40,"line":79},[38,171,172],{"class":44},"# mostra metadados (versão, autor, data de criação) — nunca o valor\n",[38,174,175,177,179,182],{"class":40,"line":85},[38,176,52],{"class":51},[38,178,56],{"class":55},[38,180,181],{"class":55}," describe",[38,183,184],{"class":55}," db_password\n",[38,186,187],{"class":40,"line":100},[38,188,76],{"emptyLinePlaceholder":75},[38,190,191],{"class":40,"line":105},[38,192,193],{"class":44},"# mostra o valor (exige permissão explícita)\n",[38,195,196,198,200,203],{"class":40,"line":111},[38,197,52],{"class":51},[38,199,56],{"class":55},[38,201,202],{"class":55}," get",[38,204,184],{"class":55},[10,206,207,210],{},[35,208,209],{},"heroctl secret get"," é a operação mais sensível do sistema. Ela aparece no log de auditoria com nome de quem leu, quando, e de qual IP.",[212,213,214],"blockquote",{},[10,215,216,220,221,224],{},[217,218,219],"strong",{},"Atenção:"," Em produção, restrinja ",[35,222,223],{},"secret:read"," ao mínimo de papéis. Para a maioria dos times, ninguém precisa ler valores manualmente — o cluster injeta direto no job.",[20,226,228],{"id":227},"criptografia-em-repouso","Criptografia em repouso",[10,230,231],{},"Cada segredo é criptografado com AES-256 antes de ser persistido. A chave de criptografia do cluster fica protegida e nunca é armazenada junto com os dados criptografados.",[10,233,234],{},"Operacionalmente isso significa que um backup do estado do cluster, sem a chave, é inútil para um atacante. Você pode subir um snapshot em disco rígido externo sem se preocupar.",[10,236,237,238,241],{},"A chave em si é gerada na inicialização do cluster e fica em arquivo protegido por permissão de filesystem (",[35,239,240],{},"0600",", owner root) em cada nó servidor. Para rotacionar:",[28,243,245],{"className":30,"code":244,"language":32,"meta":33,"style":33},"heroctl cluster rekey\n",[35,246,247],{"__ignoreMap":33},[38,248,249,251,254],{"class":40,"line":41},[38,250,52],{"class":51},[38,252,253],{"class":55}," cluster",[38,255,256],{"class":55}," rekey\n",[10,258,259],{},"Esse comando re-criptografa todos os segredos com uma chave nova e invalida a antiga. Faça em janela de manutenção — a operação pode demorar minutos em clusters com milhares de segredos.",[20,261,263],{"id":262},"injetando-no-job","Injetando no job",[10,265,266],{},"A injeção é feita no momento em que a alocação inicia. O valor descriptografado existe apenas na memória do processo, nunca em disco.",[28,268,272],{"className":269,"code":270,"language":271,"meta":33,"style":33},"language-yaml shiki shiki-themes github-dark-default","job: api-pagamentos\nenv:\n  DATABASE_URL: ${secret.database_url}\n  STRIPE_KEY: ${secret.stripe_secret}\n  REDIS_PASSWORD: ${secret.redis_password}\n","yaml",[35,273,274,287,295,305,315],{"__ignoreMap":33},[38,275,276,280,284],{"class":40,"line":41},[38,277,279],{"class":278},"sPWt5","job",[38,281,283],{"class":282},"sZEs4",": ",[38,285,286],{"class":55},"api-pagamentos\n",[38,288,289,292],{"class":40,"line":48},[38,290,291],{"class":278},"env",[38,293,294],{"class":282},":\n",[38,296,297,300,302],{"class":40,"line":72},[38,298,299],{"class":278},"  DATABASE_URL",[38,301,283],{"class":282},[38,303,304],{"class":55},"${secret.database_url}\n",[38,306,307,310,312],{"class":40,"line":79},[38,308,309],{"class":278},"  STRIPE_KEY",[38,311,283],{"class":282},[38,313,314],{"class":55},"${secret.stripe_secret}\n",[38,316,317,320,322],{"class":40,"line":85},[38,318,319],{"class":278},"  REDIS_PASSWORD",[38,321,283],{"class":282},[38,323,324],{"class":55},"${secret.redis_password}\n",[10,326,327],{},"O processo dentro do contêiner enxerga as variáveis como qualquer outra. Nenhuma alteração no código da aplicação.",[10,329,330],{},"Para injetar como arquivo (útil para chaves TLS, certificados, JSON de service account):",[28,332,334],{"className":269,"code":333,"language":271,"meta":33,"style":33},"job: webhook-handler\nfiles:\n  - path: \u002Fetc\u002Fapp\u002Fcredentials.json\n    content: ${secret.gcp_service_account}\n    mode: \"0400\"\n",[35,335,336,345,352,365,375],{"__ignoreMap":33},[38,337,338,340,342],{"class":40,"line":41},[38,339,279],{"class":278},[38,341,283],{"class":282},[38,343,344],{"class":55},"webhook-handler\n",[38,346,347,350],{"class":40,"line":48},[38,348,349],{"class":278},"files",[38,351,294],{"class":282},[38,353,354,357,360,362],{"class":40,"line":72},[38,355,356],{"class":282},"  - ",[38,358,359],{"class":278},"path",[38,361,283],{"class":282},[38,363,364],{"class":55},"\u002Fetc\u002Fapp\u002Fcredentials.json\n",[38,366,367,370,372],{"class":40,"line":79},[38,368,369],{"class":278},"    content",[38,371,283],{"class":282},[38,373,374],{"class":55},"${secret.gcp_service_account}\n",[38,376,377,380,382],{"class":40,"line":85},[38,378,379],{"class":278},"    mode",[38,381,283],{"class":282},[38,383,384],{"class":55},"\"0400\"\n",[10,386,387],{},"O arquivo é criado em tmpfs (não toca disco), com a permissão indicada, antes do processo principal subir.",[20,389,391],{"id":390},"versionamento-e-rotacao","Versionamento e rotação",[10,393,394],{},"Toda atualização de um segredo cria uma versão nova. A versão antiga fica disponível por uma janela de tempo configurável (default 7 dias) para casos de rollback.",[28,396,398],{"className":30,"code":397,"language":32,"meta":33,"style":33},"# atualiza, mantendo histórico\nheroctl secret update db_password --from-literal=\"senha-nova\"\n\n# lista versões\nheroctl secret history db_password\n\n# faz rollback para versão anterior\nheroctl secret rollback db_password --to-version 3\n",[35,399,400,405,421,425,430,441,445,450],{"__ignoreMap":33},[38,401,402],{"class":40,"line":41},[38,403,404],{"class":44},"# atualiza, mantendo histórico\n",[38,406,407,409,411,414,416,418],{"class":40,"line":48},[38,408,52],{"class":51},[38,410,56],{"class":55},[38,412,413],{"class":55}," update",[38,415,62],{"class":55},[38,417,66],{"class":65},[38,419,420],{"class":55},"\"senha-nova\"\n",[38,422,423],{"class":40,"line":72},[38,424,76],{"emptyLinePlaceholder":75},[38,426,427],{"class":40,"line":79},[38,428,429],{"class":44},"# lista versões\n",[38,431,432,434,436,439],{"class":40,"line":85},[38,433,52],{"class":51},[38,435,56],{"class":55},[38,437,438],{"class":55}," history",[38,440,184],{"class":55},[38,442,443],{"class":40,"line":100},[38,444,76],{"emptyLinePlaceholder":75},[38,446,447],{"class":40,"line":105},[38,448,449],{"class":44},"# faz rollback para versão anterior\n",[38,451,452,454,456,459,461,464],{"class":40,"line":111},[38,453,52],{"class":51},[38,455,56],{"class":55},[38,457,458],{"class":55}," rollback",[38,460,62],{"class":55},[38,462,463],{"class":65}," --to-version",[38,465,466],{"class":65}," 3\n",[10,468,469],{},"Por padrão, jobs em execução continuam usando a versão que estava ativa quando subiram. Para forçar releitura, redeploye o job:",[28,471,473],{"className":30,"code":472,"language":32,"meta":33,"style":33},"heroctl job redeploy api-pagamentos\n",[35,474,475],{"__ignoreMap":33},[38,476,477,479,482,485],{"class":40,"line":41},[38,478,52],{"class":51},[38,480,481],{"class":55}," job",[38,483,484],{"class":55}," redeploy",[38,486,487],{"class":55}," api-pagamentos\n",[10,489,490],{},"Para um job que precisa sempre da versão mais recente sem redeploy, declare:",[28,492,494],{"className":269,"code":493,"language":271,"meta":33,"style":33},"env:\n  DATABASE_URL: ${secret.database_url:latest}\n",[35,495,496,502],{"__ignoreMap":33},[38,497,498,500],{"class":40,"line":41},[38,499,291],{"class":278},[38,501,294],{"class":282},[38,503,504,506,508],{"class":40,"line":48},[38,505,299],{"class":278},[38,507,283],{"class":282},[38,509,510],{"class":55},"${secret.database_url:latest}\n",[10,512,513],{},"Nesse modo, o cluster reinicia a alocação automaticamente quando o segredo muda.",[20,515,517],{"id":516},"permissoes-por-papel-business","Permissões por papel (Business+)",[10,519,520],{},"No plano Business, você ganha controle granular sobre quem pode fazer o quê com qual segredo. O modelo trabalha com escopos hierárquicos:",[28,522,524],{"className":269,"code":523,"language":271,"meta":33,"style":33},"policy \"deploy-prod-secrets\":\n  secret:\n    path: \"prod\u002F*\"\n    capabilities: [\"read\", \"list\"]\n  secret:\n    path: \"prod\u002Fadmin\u002F*\"\n    capabilities: []  # nem listar\n",[35,525,526,533,540,550,570,576,585],{"__ignoreMap":33},[38,527,528,531],{"class":40,"line":41},[38,529,530],{"class":278},"policy \"deploy-prod-secrets\"",[38,532,294],{"class":282},[38,534,535,538],{"class":40,"line":48},[38,536,537],{"class":278},"  secret",[38,539,294],{"class":282},[38,541,542,545,547],{"class":40,"line":72},[38,543,544],{"class":278},"    path",[38,546,283],{"class":282},[38,548,549],{"class":55},"\"prod\u002F*\"\n",[38,551,552,555,558,561,564,567],{"class":40,"line":79},[38,553,554],{"class":278},"    capabilities",[38,556,557],{"class":282},": [",[38,559,560],{"class":55},"\"read\"",[38,562,563],{"class":282},", ",[38,565,566],{"class":55},"\"list\"",[38,568,569],{"class":282},"]\n",[38,571,572,574],{"class":40,"line":85},[38,573,537],{"class":278},[38,575,294],{"class":282},[38,577,578,580,582],{"class":40,"line":100},[38,579,544],{"class":278},[38,581,283],{"class":282},[38,583,584],{"class":55},"\"prod\u002Fadmin\u002F*\"\n",[38,586,587,589,592],{"class":40,"line":105},[38,588,554],{"class":278},[38,590,591],{"class":282},": []  ",[38,593,594],{"class":44},"# nem listar\n",[10,596,597,598,603],{},"Atribua a política a um token ou a um papel e pronto. Ver o documento de ",[599,600,602],"a",{"href":601},"\u002Fdocs\u002Fseguranca\u002Frbac","RBAC"," para o modelo completo.",[20,605,607],{"id":606},"auditoria-business","Auditoria (Business+)",[10,609,610],{},"Todo acesso é registrado:",[28,612,614],{"className":30,"code":613,"language":32,"meta":33,"style":33},"heroctl audit secret --name db_password --since 30d\n",[35,615,616],{"__ignoreMap":33},[38,617,618,620,623,625,628,630,633],{"class":40,"line":41},[38,619,52],{"class":51},[38,621,622],{"class":55}," audit",[38,624,56],{"class":55},[38,626,627],{"class":65}," --name",[38,629,62],{"class":55},[38,631,632],{"class":65}," --since",[38,634,635],{"class":55}," 30d\n",[10,637,638,639,563,642,563,645,648],{},"Saída tabular com timestamp, usuário, ação (",[35,640,641],{},"read",[35,643,644],{},"update",[35,646,647],{},"delete","), origem (IP), e resultado. Exporte para análise externa:",[28,650,652],{"className":30,"code":651,"language":32,"meta":33,"style":33},"heroctl audit secret --since 30d --format json > audit.jsonl\n",[35,653,654],{"__ignoreMap":33},[38,655,656,658,660,662,664,667,670,673,676],{"class":40,"line":41},[38,657,52],{"class":51},[38,659,622],{"class":55},[38,661,56],{"class":55},[38,663,632],{"class":65},[38,665,666],{"class":55}," 30d",[38,668,669],{"class":65}," --format",[38,671,672],{"class":55}," json",[38,674,675],{"class":123}," >",[38,677,678],{"class":55}," audit.jsonl\n",[10,680,681],{},"Configure alertas para padrões anômalos: leitura fora de horário comercial, mesmo segredo lido por usuários diferentes em janela curta, falhas de permissão repetidas.",[20,683,685],{"id":684},"backup-criptografado","Backup criptografado",[10,687,688],{},"Backups dos segredos saem cifrados, prontos para mandar para storage S3-compatível:",[28,690,692],{"className":269,"code":691,"language":271,"meta":33,"style":33},"# config do cluster\nbackup:\n  secrets:\n    enabled: true\n    schedule: \"0 3 * * *\"  # 3h da manhã todo dia\n    destination:\n      type: s3\n      bucket: heroctl-backups\n      region: us-east-1\n      prefix: secrets\u002F\n      credentials: ${secret.backup_s3_creds}\n    retention_days: 90\n",[35,693,694,699,706,713,723,736,743,753,763,774,785,796],{"__ignoreMap":33},[38,695,696],{"class":40,"line":41},[38,697,698],{"class":44},"# config do cluster\n",[38,700,701,704],{"class":40,"line":48},[38,702,703],{"class":278},"backup",[38,705,294],{"class":282},[38,707,708,711],{"class":40,"line":72},[38,709,710],{"class":278},"  secrets",[38,712,294],{"class":282},[38,714,715,718,720],{"class":40,"line":79},[38,716,717],{"class":278},"    enabled",[38,719,283],{"class":282},[38,721,722],{"class":65},"true\n",[38,724,725,728,730,733],{"class":40,"line":85},[38,726,727],{"class":278},"    schedule",[38,729,283],{"class":282},[38,731,732],{"class":55},"\"0 3 * * *\"",[38,734,735],{"class":44},"  # 3h da manhã todo dia\n",[38,737,738,741],{"class":40,"line":100},[38,739,740],{"class":278},"    destination",[38,742,294],{"class":282},[38,744,745,748,750],{"class":40,"line":105},[38,746,747],{"class":278},"      type",[38,749,283],{"class":282},[38,751,752],{"class":55},"s3\n",[38,754,755,758,760],{"class":40,"line":111},[38,756,757],{"class":278},"      bucket",[38,759,283],{"class":282},[38,761,762],{"class":55},"heroctl-backups\n",[38,764,766,769,771],{"class":40,"line":765},9,[38,767,768],{"class":278},"      region",[38,770,283],{"class":282},[38,772,773],{"class":55},"us-east-1\n",[38,775,777,780,782],{"class":40,"line":776},10,[38,778,779],{"class":278},"      prefix",[38,781,283],{"class":282},[38,783,784],{"class":55},"secrets\u002F\n",[38,786,788,791,793],{"class":40,"line":787},11,[38,789,790],{"class":278},"      credentials",[38,792,283],{"class":282},[38,794,795],{"class":55},"${secret.backup_s3_creds}\n",[38,797,799,802,804],{"class":40,"line":798},12,[38,800,801],{"class":278},"    retention_days",[38,803,283],{"class":282},[38,805,806],{"class":65},"90\n",[10,808,809],{},"O snapshot é cifrado com a chave do cluster antes de ser enviado. O bucket pode estar acessível para outros propósitos sem risco — quem tiver acesso de leitura não consegue descriptografar nada.",[10,811,812,813,816],{},"Para restaurar em um cluster novo, você precisa do snapshot ",[217,814,815],{},"e"," da chave do cluster original. Guarde a chave separada do storage de backup.",[20,818,820],{"id":819},"cofres-externos","Cofres externos",[10,822,823],{},"Para times com requisitos de conformidade que exigem uso de cofre corporativo já existente, há integração opcional:",[28,825,827],{"className":269,"code":826,"language":271,"meta":33,"style":33},"secret_backend:\n  type: aws_kms\n  region: us-east-1\n  key_id: alias\u002Fheroctl-prod\n",[35,828,829,836,846,855],{"__ignoreMap":33},[38,830,831,834],{"class":40,"line":41},[38,832,833],{"class":278},"secret_backend",[38,835,294],{"class":282},[38,837,838,841,843],{"class":40,"line":48},[38,839,840],{"class":278},"  type",[38,842,283],{"class":282},[38,844,845],{"class":55},"aws_kms\n",[38,847,848,851,853],{"class":40,"line":72},[38,849,850],{"class":278},"  region",[38,852,283],{"class":282},[38,854,773],{"class":55},[38,856,857,860,862],{"class":40,"line":79},[38,858,859],{"class":278},"  key_id",[38,861,283],{"class":282},[38,863,864],{"class":55},"alias\u002Fheroctl-prod\n",[10,866,867,868,871],{},"Suportado de fábrica: AWS KMS, GCP KMS, HashiCorp Vault. Nesse modo, o HeroCtl delega operações de criptografia ao cofre externo. Os segredos continuam acessíveis pela mesma sintaxe ",[35,869,870],{},"${secret.nome}",".",[10,873,874],{},"Use isso se você já tem o cofre operando e auditado. Para a maioria dos times, o backend nativo é suficiente e mais simples.",[20,876,878],{"id":877},"boas-praticas","Boas práticas",[10,880,881],{},"Em ordem de importância:",[883,884,885,892,905,911,920,926],"ol",{},[886,887,888,891],"li",{},[217,889,890],{},"Sem hardcode em spec."," Nem em commit, nem temporariamente, nem \"só para teste\". O hábito vaza.",[886,893,894,897,898,563,901,904],{},[217,895,896],{},"Separação dev \u002F staging \u002F prod."," Use prefixos no nome (",[35,899,900],{},"dev\u002Fdb_password",[35,902,903],{},"prod\u002Fdb_password",") ou clusters separados. Nunca compartilhe credencial de produção com ambiente de desenvolvimento.",[886,906,907,910],{},[217,908,909],{},"Rotação periódica."," Mínimo a cada 90 dias para credenciais de banco e provedores. Mais frequente para tokens de API que vazam fácil.",[886,912,913,916,917,919],{},[217,914,915],{},"Least privilege na leitura."," Quase ninguém precisa de ",[35,918,223],{},". A injeção automática no job não exige que a pessoa que fez deploy tenha acesso ao valor.",[886,921,922,925],{},[217,923,924],{},"Revisão de auditoria mensal."," Olhe quem leu o quê. Anomalias aparecem se você procura.",[886,927,928,931,932,935],{},[217,929,930],{},"Não loga segredo."," Configure a aplicação para mascarar variáveis sensíveis em logs. O cluster cifra em repouso, mas se sua aplicação imprime ",[35,933,934],{},"print(os.environ)"," no startup, acabou.",[20,937,939],{"id":938},"proximos-passos","Próximos passos",[941,942,943,950],"ul",{},[886,944,945,946,949],{},"Configurar ",[599,947,948],{"href":601},"RBAC e tokens"," para limitar quem acessa o quê.",[886,951,952,953,957],{},"Revisar ",[599,954,956],{"href":955},"\u002Fdocs\u002Fobservabilidade\u002Fmetricas-logs","métricas e logs"," para detectar uso anômalo.",[959,960,961],"style",{},"html pre.shiki code .sH3jZ, html code.shiki .sH3jZ{--shiki-default:#8B949E}html pre.shiki code .sQhOw, html code.shiki .sQhOw{--shiki-default:#FFA657}html pre.shiki code .s9uIt, html code.shiki .s9uIt{--shiki-default:#A5D6FF}html pre.shiki code .sFSAA, html code.shiki .sFSAA{--shiki-default:#79C0FF}html pre.shiki code .suJrU, html code.shiki .suJrU{--shiki-default:#FF7B72}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sPWt5, html code.shiki .sPWt5{--shiki-default:#7EE787}html pre.shiki code .sZEs4, html code.shiki .sZEs4{--shiki-default:#E6EDF3}",{"title":33,"searchDepth":48,"depth":48,"links":963},[964,965,966,967,968,969,970,971,972,973,974],{"id":22,"depth":48,"text":23},{"id":143,"depth":48,"text":144},{"id":227,"depth":48,"text":228},{"id":262,"depth":48,"text":263},{"id":390,"depth":48,"text":391},{"id":516,"depth":48,"text":517},{"id":606,"depth":48,"text":607},{"id":684,"depth":48,"text":685},{"id":819,"depth":48,"text":820},{"id":877,"depth":48,"text":878},{"id":938,"depth":48,"text":939},"seguranca","Como guardar senhas, tokens e chaves fora do spec do job, com criptografia em repouso e rotação versionada.",false,"md","i-lucide-key","2026-04-26",{},"\u002Fdocs\u002Fseguranca\u002Fsecrets",[],"8 min",{"title":5,"description":976},"docs\u002Fseguranca\u002Fsecrets",[988,975,989,990],"secrets","criptografia","rotacao","MnupwplOQri_nz4oDH7NuenhZMjkzAOtVj-zPqneZ54",[993,999,1005,1010,1016,1020,1026,1031,1036,1041,1047,1051,1055,1056],{"path":994,"title":995,"description":996,"category":997,"order":41,"icon":998},"\u002Fdocs\u002Fapi\u002Freferencia-api","Referência da API REST","Endpoints, autenticação JWT, exemplos com curl e padrões de erro da API do HeroCtl.","api","i-lucide-code",{"path":1000,"title":1001,"description":1002,"category":1003,"order":41,"icon":1004},"\u002Fdocs\u002Fdeploy\u002Fprimeiro-deploy","Deploy do primeiro app","Suba uma aplicação Node.js com banco Postgres em 50 linhas de YAML. Inclui health check, rolling deploy e rollback.","deploy","i-lucide-rocket",{"path":1006,"title":1007,"description":1008,"category":1003,"order":48,"icon":1009},"\u002Fdocs\u002Fdeploy\u002Frolling-canary-bluegreen","Rolling, canary, blue-green e rainbow","Quatro estratégias de deploy. Quando usar cada uma, com exemplos completos e trade-offs honestos.","i-lucide-git-branch",{"path":1011,"title":1012,"description":1013,"category":1014,"order":48,"icon":1015},"\u002Fdocs\u002Fobservabilidade\u002Fbackup-restore","Backup e restore do estado do cluster","Como salvar, agendar e restaurar snapshots do plano de controle do HeroCtl. Estratégia de disaster recovery.","observabilidade","i-lucide-archive",{"path":955,"title":1017,"description":1018,"category":1014,"order":41,"icon":1019},"Métricas e logs","Coleta de métricas, logs e traces sem montar uma pilha de observabilidade externa. Quando vale, e quando integrar com ferramenta de fora.","i-lucide-activity",{"path":1021,"title":1022,"description":1023,"category":1024,"order":72,"icon":1025},"\u002Fdocs\u002Foperacoes\u002Fcomandos-cli","Referência completa do CLI","Todos os comandos heroctl com sinopse, flags e exemplo. Use como cola de mesa.","operacoes","i-lucide-terminal",{"path":1027,"title":1028,"description":1029,"category":1024,"order":41,"icon":1030},"\u002Fdocs\u002Foperacoes\u002Finstalacao","Instalação","Instale o HeroCtl em qualquer servidor Linux com Docker em um único comando. Cobre pré-requisitos, bootstrap e verificação.","i-lucide-download",{"path":1032,"title":1033,"description":1034,"category":1024,"order":79,"icon":1035},"\u002Fdocs\u002Foperacoes\u002Fmulti-region","Multi-region (em planejamento Q4 2026)","O que esperar de multi-region no HeroCtl, como rodar em várias regiões hoje e o roadmap até 2027.","i-lucide-globe",{"path":1037,"title":1038,"description":1039,"category":1024,"order":48,"icon":1040},"\u002Fdocs\u002Foperacoes\u002Fprimeiro-cluster","Subir cluster de 3 nós","Forme um cluster com 3 servidores em menos de 10 minutos. Tolera falha de 1 nó sem indisponibilidade.","i-lucide-network",{"path":1042,"title":1043,"description":1044,"category":1045,"order":48,"icon":1046},"\u002Fdocs\u002Frede\u002Ffirewall","Configuração de firewall","Quais portas o HeroCtl usa, quais precisam ficar abertas, e quais nunca deveriam ser expostas à internet.","rede","i-lucide-shield",{"path":1048,"title":1049,"description":1050,"category":1045,"order":41,"icon":1035},"\u002Fdocs\u002Frede\u002Fingress-tls","Ingress e TLS automático","Como expor aplicações pela porta 443 com certificados emitidos e renovados automaticamente, sem operar um roteador externo.",{"path":601,"title":1052,"description":1053,"category":975,"order":48,"icon":1054},"RBAC e controle de acesso (Business+)","Modelo de papéis, políticas e tokens para limitar quem pode submeter, ler e operar o cluster.","i-lucide-users",{"path":982,"title":5,"description":976,"category":975,"order":41,"icon":979},{"path":1057,"title":1058,"description":1059,"category":1060,"order":41,"icon":1061},"\u002Fdocs\u002Ftroubleshooting\u002Fproblemas-comuns","Troubleshooting de problemas comuns","Os 12 problemas mais frequentes em clusters HeroCtl, com sintoma, diagnóstico e correção passo a passo.","troubleshooting","i-lucide-alert-triangle",1777362179369]