Escopo
O NIST Cybersecurity Framework costuma ser aplicado de forma genérica demais em times de produto. Alguém mapeia alguns controles em uma planilha, declara que o sistema está conforme, e o primeiro bug de isolamento entre tenants prova que aquele mapa nunca descreveu a aplicação real. Para uma aplicação web ou plataforma SaaS, a unidade útil não é um checklist genérico. A unidade útil é um perfil conectado aos ativos de produção, às decisões de risco, à telemetria e às evidências.
Este artigo constrói um perfil técnico de CSF 2.0 para um produto SaaS multi-tenant. Ele usa as seis funções do CSF, Govern, Identify, Protect, Detect, Respond e Recover, e conecta essas funções a controles concretos: autenticação, autorização por tenant, entrega segura, logs, resposta a incidentes e recuperação. Onde o CSF define resultados esperados, o time SaaS precisa fornecer implementação e prova.
O que é o CSF
O CSF 2.0 é um framework orientado a resultados esperados. Ele não diz para um time usar middleware Next.js, row level security no PostgreSQL, OIDC, SAST ou um serviço específico de cloud. Ele oferece uma linguagem comum para cibersegurança e governança de risco. Para detalhes de implementação, times web e SaaS normalmente combinam o CSF com referências como NIST CSF 2.0, NIST SP 800-218 SSDF, NIST SP 800-53 Rev. 5 e NIST SP 800-63B-4.
Essa distinção importa. Um time SaaS não deveria afirmar que o CSF explica como implementar armazenamento de sessão ou autorização de API. O CSF diz quais resultados precisam existir. O perfil de engenharia diz como esta aplicação sustenta esses resultados, como o time mede isso e quais evidências provam o que foi implementado.
Modelo de perfil
Comece com um perfil que nomeia o sistema de produção e o apetite de risco. Se o perfil não identifica ativos críticos, responsáveis e tempos-alvo de resposta, ele ainda não é operacional. O exemplo abaixo é pequeno, mas captura decisões que deveriam guiar arquitetura e prioridade de backlog.
profile: name: web-saas-production framework: NIST CSF 2.0 tier_target: repeatable systems: - public_web_app - api_gateway - identity_provider - tenant_database - object_storage - ci_cd crown_jewels: - tenant_data - session_tokens - signing_keys - billing_webhooks risk_appetite: public_auth_bypass: zero_tolerance tenant_isolation_failure: zero_tolerance p1_detection_target: 5m p1_containment_target: 30mO movimento importante é definir resultados inaceitáveis em linguagem de produto. Para a maioria das plataformas SaaS, bypass de autenticação pública e cruzamento de dados entre tenants são eventos de tolerância zero. Isso não significa que a probabilidade é zero. Significa que a organização não aceita o risco sem tratamento, então controles e detecção precisam ser desenhados em torno dele.
Govern e Identify
Govern é onde o CSF 2.0 fica útil para a liderança de um SaaS. O time precisa definir quem é dono do risco, como os riscos são escalados, como fornecedores são avaliados e quais decisões de produto exigem revisão de segurança. Identify transforma essa governança em um mapa de ativos, dependências, fluxos de dados e impacto de negócio.
Para uma aplicação web, o inventário mínimo útil inclui rotas públicas, APIs internas, background jobs, provedores de identidade, fontes de webhooks, bancos e armazenamentos de dados, buckets de objetos, segredos, runners de CI, ferramentas administrativas e processadores terceiros. Cada item precisa de responsável, classe de dado, premissa de isolamento por tenant, nível de exposição e expectativa de logs. Sem esse inventário, Protect e Detect vão operar no escuro.
risk: id: SAAS-RISK-014 scenario: tenant A can read tenant B records through an authorization flaw affected_assets: - api.users - tenant_database mapped_outcomes: - GV.RM: risk management strategy - ID.AM: assets are understood - PR.AA: identities and access are managed - DE.CM: systems are monitored - RS.MA: incidents are managed likelihood: medium impact: critical owner: platform-security treatment: mitigate evidence: - row_level_security_policy - authorization_test_suite - cross_tenant_query_alert - incident_playbook_tenant_data_exposureO registro de riscos é só metade do trabalho. Cada categoria precisa de um controle, um responsável e uma evidência que já exista no fluxo de engenharia. Uma matriz útil para o cenário de isolamento de tenant pode ser assim:
controls: - csf_category: GV.RM saas_control: risk appetite is defined for auth bypass and tenant isolation owner: head_of_engineering evidence: - approved risk register - quarterly risk review notes - csf_category: ID.AM saas_control: production assets and data flows are inventoried by tenant impact owner: platform_security evidence: - service catalog - data flow diagram - public route inventory - csf_category: PR.AA saas_control: every tenant scoped read and write enforces subject, tenant and action owner: application_engineering evidence: - authorization middleware - row level security policy - negative access tests - csf_category: DE.CM saas_control: denied cross-tenant access and privilege changes emit security events owner: security_operations evidence: - alert rule - log schema - detection test - csf_category: RS.MA saas_control: tenant data exposure has a P1 incident playbook owner: incident_commander evidence: - playbook - tabletop exercise record - post-incident review template - csf_category: RC.RP saas_control: recovery requires patched code, regression test and monitored rollout owner: release_engineering evidence: - deployment record - regression test result - 48h monitoring reportProtect
Protect é onde a maior parte do trabalho de segurança SaaS aparece, mas ele não deve ser reduzido a cabeçalhos HTTP e varredura de dependências. Os controles centrais são identidade, autorização, proteção de dados, configuração segura, gestão de segredos, controle de mudanças e desenvolvimento seguro.
A autenticação deve acompanhar o risco da ação. Uma página comum de conta pode aceitar uma sessão com menor nível de garantia, enquanto alterações de cobrança, criação de API keys, impersonação administrativa e jobs de exportação deveriam exigir autenticação mais forte ou reautenticação recente. A autorização precisa ser centralizada o suficiente para ser testável, mas próxima o suficiente do acesso a dados para que uma verificação esquecida no controller não exponha registros.
type Session = { userId: string; tenantId: string; assuranceLevel: "aal1" | "aal2" | "aal3";}; type RequestContext = { session: Session; routeTenantId: string; requiredAssuranceLevel?: Session["assuranceLevel"];}; export function enforceTenantBoundary(ctx: RequestContext) { if (ctx.session.tenantId !== ctx.routeTenantId) { auditSecurityEvent("tenant_boundary_denied", { userId: ctx.session.userId, sessionTenantId: ctx.session.tenantId, routeTenantId: ctx.routeTenantId, }); throw new ForbiddenError("tenant boundary violation"); } if ( ctx.requiredAssuranceLevel === "aal2" && ctx.session.assuranceLevel === "aal1" ) { throw new StepUpRequiredError("stronger authentication required"); }}Verificações na aplicação são necessárias, mas não bastam para dados multi-tenant. Se o banco suporta row level security, use isso como uma segunda camada de isolamento para tabelas de alto valor. O runtime deve definir o contexto do tenant depois da autenticação e antes das consultas.
create policy tenant_isolation on customer_records using (tenant_id = current_setting('app.tenant_id')::uuid); alter table customer_records enable row level security; grant select, insert, update, delete on customer_records to app_runtime;Entrega segura
O SSDF é o documento NIST mais adequado para detalhes de entrega de software. Use-o para tornar CSF Protect mensurável no pipeline: revisão de código, revisão de dependências, secret scanning, SAST, testes unitários de segurança, varredura de containers, verificações de política de infraestrutura e proveniência de artefatos de produção.
name: security-gates on: pull_request: jobs: appsec: runs-on: ubuntu-latest permissions: contents: read security-events: write steps: - uses: actions/checkout@v4 - name: dependency review uses: actions/dependency-review-action@v4 - name: semgrep run: semgrep ci --config p/owasp-top-ten - name: unit and authorization tests run: npm run test:securityNão bloqueie todo pull request com todo scanner possível. Isso cria fadiga de alertas e uma cultura de bypass. Bloqueie apenas nas verificações de alto sinal que mapeiam riscos reais do perfil. Testes de autorização por tenant, revisão de dependências para pacotes vulneráveis alcançáveis e secret scanning normalmente merecem bloqueio obrigatório. DAST longo e testes de abuso podem rodar de forma agendada ou antes de uma release.
Detect
Detect falha quando logs são tratados como sobra operacional. Um perfil de segurança SaaS precisa de casos explícitos de detecção. Para isolamento de tenant, eventos úteis incluem acesso negado entre tenants, aumento repentino de 403, mudanças de privilégio, impersonação administrativa, anomalias em volume de exportação, falhas suspeitas em webhooks e acesso vindo de geografia impossível.
{ "event": "tenant_boundary_denied", "time": "2026-06-30T14:42:10.113Z", "trace_id": "f7d1b57798f54db9", "actor": { "user_id": "usr_8g9", "tenant_id": "ten_blue" }, "target": { "tenant_id": "ten_red", "resource": "customer_records" }, "decision": "deny", "reason": "tenant_mismatch", "mapped_outcomes": ["PR.AA", "DE.CM", "RS.AN"]}Todo evento de segurança deve carregar contexto suficiente para a resposta: ator, tenant, alvo, decisão, motivo, rota, trace id, versão do deploy e resultado mapeado. Evite registrar segredos brutos, tokens de sessão, dados de pagamento ou dados pessoais desnecessários. Qualidade de detecção vem de eventos estruturados, não de coletar tudo.
Respond e Recover
Respond e Recover são onde times SaaS frequentemente descobrem que só estavam preparados para indisponibilidade de infraestrutura. Um playbook de incidente de segurança precisa lidar com preservação de evidências, contenção, revisão jurídica, análise de impacto por tenant, rotação de segredos e restauração segura do serviço.
playbook: tenant-data-exposureseverity: p1trigger: - tenant_boundary_denied spikes above baseline - confirmed cross-tenant readactions: detect: - preserve traces, logs, database audit records and request bodies metadata - identify affected tenants, users, endpoints and deployment version contain: - disable vulnerable endpoint or feature flag - revoke suspicious sessions and rotate exposed application secrets - freeze destructive jobs that can propagate corrupted access state eradicate: - patch authorization defect - add regression test for the exact access path - run targeted data access review recover: - restore endpoint with guarded rollout - monitor denials, privilege changes and anomalous reads for 48h communicate: - legal and privacy owner approve tenant notification - support receives tenant-specific impact factsRecuperação não é apenas colocar o serviço de volta online. Ela inclui provar que o defeito foi corrigido, verificar caminhos de dados afetados, monitorar recorrência e registrar aprendizados como novos testes, alertas ou mudanças de arquitetura. Se o incidente não deixa controles mais fortes, o perfil não evoluiu.
Evidências de engenharia
Um perfil CSF se torna crível quando cada resultado esperado tem evidência que um engenheiro, auditor ou líder de incidente consegue inspecionar. A evidência deve ser gerada pelo fluxo normal de entrega e operação, não montada manualmente no fim do trimestre.
Boas evidências incluem testes de autorização passando, migrations, decisões de policy-as-code, registros de revisão de código, atestados de deploy, definições de alertas, exercícios de incidente, revisões de acesso e métricas de produção. É aqui também que a leitura de diffs importa. Mudanças de segurança devem deixar a redução de risco óbvia na revisão.
diff --git a/src/api/customer-records.ts b/src/api/customer-records.ts@@-const rows = await db.customerRecords.findMany({- where: { id: recordId },-});+const rows = await db.customerRecords.findMany({+ where: {+ id: recordId,+ tenantId: ctx.session.tenantId,+ },+}); if (rows.length === 0) { throw new NotFoundError();}Erros comuns
O primeiro erro é tratar CSF como selo de certificação. CSF é um framework para gerenciar risco de cibersegurança, não um adesivo de segurança de produto. O segundo erro é mapear tudo para um controle sem nomear o cenário de risco. Um controle sem cenário é difícil de priorizar e fácil de interpretar errado.
O terceiro erro é ignorar limites entre tenants. Controles web single-tenant não ficam automaticamente seguros em SaaS. O quarto erro é construir detecção depois que a funcionalidade já foi lançada. Se eventos de segurança não são desenhados junto com a funcionalidade, o time não terá os dados necessários durante o incidente.
Checklist prático
Para cada funcionalidade crítica de SaaS, escreva um cenário de risco, mapeie esse cenário para resultados do CSF, defina controles preventivos, eventos de detecção, ações de resposta e prova de recuperação. Mantenha o perfil pequeno o suficiente para ser revisado a cada release.
Um primeiro marco forte é um perfil de isolamento de tenant com cinco artefatos: inventário de ativos e fluxos de dados, testes centralizados de autorização, policy de isolamento no banco, eventos de segurança estruturados e um playbook P1. Esse conjunto dá governança para liderança, controles para engenharia, detecção e recuperação em um recorte focado.