Segurança por Design em SaaS: Melhores Práticas para CTOs
Como construir segurança no produto desde o início — não como camada adicional depois. Os controles que todo SaaS precisa antes de ir para produção.
Por que segurança adicionada depois é mais cara
Segurança implementada depois do MVP tem dois problemas: é mais cara de implementar (porque precisa ser retroativa a código existente) e é menos efetiva (porque as decisões de arquitetura já foram tomadas sem considerar segurança).
Um exemplo concreto: se você não projetou o modelo de autorização desde o início com o tenant_id em toda operação sensível, adicioná-lo depois significa auditar e modificar potencialmente centenas de endpoints.
Segurança por design não significa segurança perfeita — significa que as decisões arquiteturais fundamentais não criam vulnerabilidades estruturais.
Os 6 princípios de segurança por design
1. Menor privilégio
Cada componente do sistema — usuário, serviço, chave de API, role de IAM — deve ter apenas as permissões que precisa para funcionar. Nada mais.
Prática:
- IAM roles de ECS tasks com acesso apenas ao S3 bucket específico que precisam
- Usuário de banco com acesso apenas às tabelas que o serviço usa (não
GRANT ALL) - API keys com escopos limitados (read-only quando não precisa escrever)
-- Errado: um usuário com acesso a tudo
GRANT ALL ON ALL TABLES IN SCHEMA public TO app_user;
-- Certo: acesso específico por tabela
GRANT SELECT, INSERT, UPDATE ON users, subscriptions TO app_user;
GRANT SELECT ON plans TO app_user;
-- Sem acesso a audit_logs, admin_configs, etc.
2. Defense in depth (defesa em camadas)
Não dependa de um único controle de segurança. Cada camada deve ser independente.
Usuário malicioso
→ Bloqueado por: Rate limiting (Nginx/WAF)
→ Bloqueado por: Validação de input (API layer)
→ Bloqueado por: Autenticação JWT verificada
→ Bloqueado por: Autorização por tenant e role
→ Bloqueado por: Row-Level Security no PostgreSQL
Se um controle falhar, o próximo ainda protege.
3. Fail securely
Quando algo dá errado, falhe de forma segura — negue acesso em vez de permitir.
// Errado: em caso de erro, permite acesso
async function checkPermission(userId: string, resource: string): Promise<boolean> {
try {
return await db.query('SELECT has_permission($1, $2)', [userId, resource])
} catch (error) {
return true // NUNCA faça isso
}
}
// Certo: em caso de erro, nega acesso
async function checkPermission(userId: string, resource: string): Promise<boolean> {
try {
return await db.query('SELECT has_permission($1, $2)', [userId, resource])
} catch (error) {
logger.error('permission_check_failed', { userId, resource, error })
return false // Nega por padrão
}
}
4. Validação de input em toda boundary externa
Nunca confie em dados que vêm de fora do sistema: requests HTTP, mensagens de fila, arquivos de upload, webhooks.
import { z } from 'zod'
const CreateUserSchema = z.object({
name: z.string().min(1).max(100).trim(),
email: z.string().email().toLowerCase(),
role: z.enum(['admin', 'member', 'viewer']),
})
// Em todo handler de API:
const result = CreateUserSchema.safeParse(req.body)
if (!result.success) {
return res.status(422).json({ error: result.error.issues })
}
// A partir daqui, result.data é type-safe e validado
5. Criptografia para dados sensíveis
Define o que é sensível e criptografe consistentemente:
| Dado | Tratamento | |---|---| | Senha | Hash com Argon2id (nunca MD5/SHA1) | | Token de API | Hash com SHA256 (guarde só o hash) | | Dados pessoais sensíveis | AES-256-GCM com chave gerenciada no KMS | | Dados de cartão | Tokenize via Stripe/Asaas — nunca armazene | | PII em logs | Pseudonimize antes de logar |
6. Auditabilidade
Toda ação sensível deve ser logável e rastreável:
// Eventos que precisam de audit log
const AUDIT_EVENTS = [
'user.created', 'user.deleted', 'user.role_changed',
'tenant.settings_changed', 'billing.plan_changed',
'data.exported', 'api_key.created', 'api_key.revoked',
]
async function auditLog(event: string, actor: { userId: string, tenantId: string }, details: object) {
await db.insert('audit_logs', {
event,
actor_user_id: actor.userId,
tenant_id: actor.tenantId,
details: JSON.stringify(details),
ip_address: requestContext.ip,
created_at: new Date(),
})
}
Checklist de segurança pré-produção
Autenticação
- [ ] Senhas com Argon2id (trabalho computacional ≥ 3)
- [ ] JWT com expiração curta (15–60 minutos) + refresh token rotativo
- [ ] Refresh tokens com rotação e detecção de reutilização
- [ ] Rate limiting em
/login,/register,/forgot-password - [ ] Bloqueio temporário após 10 tentativas inválidas
Autorização
- [ ] Todo endpoint verifica autenticação E autorização
- [ ]
tenant_idverificado em toda query de dado do cliente - [ ] Funções admin separadas de funções de usuário
- [ ] Row-Level Security habilitado no PostgreSQL (se aplicável)
Proteção da API
- [ ] HTTPS em todos os ambientes (sem exceção)
- [ ] Headers de segurança:
CSP,HSTS,X-Frame-Options,X-Content-Type-Options - [ ] CORS configurado com
allowedOriginsexplícito (sem*) - [ ] Rate limiting global por IP e por usuário autenticado
- [ ] Tamanho máximo de request configurado (proteção contra payloads gigantes)
Dados
- [ ] Inputs validados com schema (Zod, Joi ou similar)
- [ ] Queries parametrizadas (sem concatenação de strings em SQL)
- [ ] Uploads de arquivo: tipo MIME verificado, tamanho limitado, escaneado se necessário
- [ ] Logs sem PII ou com pseudonimização
Dependências
- [ ]
pnpm audit/npm auditno CI — bloqueio para CVEs críticos - [ ] Dependabot ou Renovate configurado para PRs automáticos de atualização
Secrets
- [ ] Nenhuma chave de API, senha ou token no código ou no
.envcommitado - [ ] Secrets em AWS Secrets Manager ou similar
- [ ]
.env.examplecom valores fictícios, sem valores reais
O que fazer quando encontra uma vulnerabilidade
- Avalie a severidade usando CVSS score
- Contenha: disable a funcionalidade vulnerável se necessário
- Não anuncie publicamente até ter o patch pronto
- Desenvolva e teste o patch em ambiente isolado
- Deploy emergencial com processo acelerado de aprovação
- Postmortem documentado internamente
- Se dados de usuários foram afetados: notifique conforme LGPD/GDPR
A Codevops faz revisões de segurança e implementa todos esses controles como parte do ciclo de desenvolvimento.
Solicitar auditoria de segurança → · SOC 2 e LGPD para SaaS → · Falar com especialista →
Precisa de ajuda com segurança & compliance?
A Codevops transforma ideias em produtos reais. Cuidamos de toda a parte técnica para que você foque no seu negócio. Respondemos em até 12 horas.
Falar com especialista →