JSON Schema lgpd.md
Um arquivo JSON que descreve a estrutura exata do frontmatter YAML. Rode contra o seu lgpd.md e descubra se está tudo certo — ou o que falta corrigir.
Última atualização:
JSON Schema Draft-07 · ~5 KB · Compatível com ajv, jsonschema, check-jsonschema
Como validar seu lgpd.md
O fluxo é direto: extraia o frontmatter YAML, converta para objeto e valide contra o schema. Três linhas de código na maioria das linguagens. Abaixo, os cenários mais comuns.
Node.js com ajv
O validador mais rápido do ecossistema JS. Suporta Draft-07 nativamente.
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
import schema from './lgpd-md-schema.json';
import { parse } from 'yaml';
import { readFileSync } from 'fs';
const ajv = new Ajv({ strict: false });
addFormats(ajv);
const validate = ajv.compile(schema);
// Extrair frontmatter do lgpd.md
const content = readFileSync('lgpd.md', 'utf-8');
const frontmatter = content.split('---')[1];
const data = parse(frontmatter);
if (validate(data)) {
console.log('✓ lgpd.md válido');
} else {
console.error('✗ Erros:', validate.errors);
}Python com jsonschema
Biblioteca padrão da comunidade Python para validação de schemas.
import json, yaml
from jsonschema import validate, ValidationError
with open("lgpd-md-schema.json") as f:
schema = json.load(f)
with open("lgpd.md") as f:
content = f.read()
frontmatter = content.split("---")[1]
data = yaml.safe_load(frontmatter)
try:
validate(instance=data, schema=schema)
print("✓ lgpd.md válido")
except ValidationError as e:
print(f"✗ Erro: {e.message}")CI/CD — GitHub Actions
Valide a cada push. Se o frontmatter quebrar, o pipeline avisa antes do deploy.
# .github/workflows/validate-lgpd.yml
name: Validar lgpd.md
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npx ajv-cli validate -s lgpd-md-schema.json -d lgpd.md.jsonVS Code — Validação em tempo real
Autocompletar e erros inline enquanto edita. Basta uma linha no topo do YAML.
# yaml-language-server: $schema=https://lgpd.md/schema.jsonRequer a extensão YAML (Red Hat) instalada.
Schema completo
Abaixo, o schema na íntegra. Define campos obrigatórios (version, controller, legal_bases, data_subjects_rights, data_categories) e opcionais (dpo, cookies, international_transfer, third_party_sharing).
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://lgpd.md/schema.json",
"title": "lgpd.md",
"description": "Schema de validação para o frontmatter YAML do arquivo lgpd.md — Declaração de Conformidade LGPD (Lei 13.709/2018).",
"type": "object",
"required": [
"spec",
"atualizado",
"expira",
"status",
"controlador",
"encarregado",
"direitos",
"politica",
"bases_legais"
],
"properties": {
"spec": {
"type": "string",
"description": "Versão da spec lgpd.md.",
"enum": ["1.0"]
},
"atualizado": {
"type": "string",
"format": "date",
"description": "Data da última atualização do arquivo (ISO 8601: YYYY-MM-DD)."
},
"expira": {
"type": "string",
"format": "date",
"description": "Data de expiração — o arquivo deve ser revisado antes desta data (ISO 8601: YYYY-MM-DD)."
},
"status": {
"type": "string",
"description": "Estado declarado de conformidade com a LGPD.",
"enum": ["conforme", "parcial", "em-adequação"]
},
"controlador": {
"type": "object",
"description": "Identificação do controlador de dados (Art. 41, §1º).",
"required": ["nome", "contato"],
"properties": {
"nome": {
"type": "string",
"description": "Razão social ou nome do controlador."
},
"cnpj": {
"type": "string",
"description": "CNPJ do controlador (obrigatório para pessoa jurídica).",
"pattern": "^\\d{2}\\.\\d{3}\\.\\d{3}/\\d{4}-\\d{2}$"
},
"contato": {
"type": "string",
"description": "Email ou URL de contato para questões de privacidade."
}
},
"additionalProperties": false
},
"encarregado": {
"type": "object",
"description": "Identificação do Encarregado/DPO (Art. 41).",
"required": ["nome", "contato"],
"properties": {
"nome": {
"type": "string",
"description": "Nome do Encarregado de Proteção de Dados."
},
"contato": {
"type": "string",
"description": "Email ou URL de contato do Encarregado."
}
},
"additionalProperties": false
},
"direitos": {
"type": "object",
"description": "Canal para exercício dos direitos do titular (Art. 18).",
"required": ["canal", "prazo"],
"properties": {
"canal": {
"type": "string",
"description": "URL ou email para exercício de direitos do titular."
},
"prazo": {
"type": "integer",
"description": "Prazo máximo de resposta em dias (Art. 19, II — máximo 15 dias).",
"minimum": 1,
"maximum": 15
}
},
"additionalProperties": false
},
"politica": {
"type": "object",
"description": "Referência à política de privacidade completa (Art. 9º).",
"required": ["url"],
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "URL da política de privacidade completa."
},
"idioma": {
"type": "string",
"description": "Código de idioma da política (BCP 47).",
"default": "pt-br"
},
"atualizada": {
"type": "string",
"format": "date",
"description": "Data da última atualização da política de privacidade."
}
},
"additionalProperties": false
},
"cookies": {
"type": "object",
"description": "Declaração sobre consentimento de cookies (obrigatório se o site usa cookies não essenciais).",
"required": ["banner", "opt_in_previo", "rejeitar_todos"],
"properties": {
"banner": {
"type": "boolean",
"description": "Exibe banner de consentimento antes de cookies não essenciais."
},
"opt_in_previo": {
"type": "boolean",
"description": "Nenhum cookie não essencial é setado antes do aceite (Art. 8, §4º)."
},
"rejeitar_todos": {
"type": "boolean",
"description": "Botão 'Rejeitar Todos' com mesma proeminência visual que 'Aceitar' (Art. 8 — consentimento livre)."
},
"gerenciar_preferencias": {
"type": "boolean",
"description": "Modal de preferências granular por categoria de finalidade."
}
},
"additionalProperties": false
},
"bases_legais": {
"type": "array",
"description": "Mapeamento de finalidades, bases legais e dados tratados (Art. 7 + Art. 9º).",
"minItems": 1,
"items": {
"type": "object",
"required": ["finalidade", "base", "dados"],
"properties": {
"finalidade": {
"type": "string",
"description": "Descrição da finalidade do tratamento."
},
"base": {
"type": "string",
"description": "Base legal utilizada.",
"enum": [
"consentimento",
"obrigação legal",
"administração pública",
"pesquisa",
"execução de contrato",
"exercício regular de direitos",
"proteção da vida",
"tutela da saúde",
"legítimo interesse",
"proteção do crédito"
]
},
"artigo": {
"type": "string",
"description": "Referência ao artigo da LGPD (ex: 'Art. 7, I')."
},
"dados": {
"type": "array",
"description": "Categorias de dados pessoais tratados para esta finalidade.",
"items": {
"type": "string"
},
"minItems": 1
}
},
"additionalProperties": false
}
},
"transferencia_internacional": {
"type": "object",
"description": "Declaração sobre transferência internacional de dados (Art. 33). Obrigatório se transfere dados para fora do Brasil.",
"required": ["transfere"],
"properties": {
"transfere": {
"type": "boolean",
"description": "Indica se há transferência internacional de dados pessoais."
},
"destinos": {
"type": "array",
"description": "Países ou regiões de destino dos dados.",
"items": {
"type": "string"
}
},
"mecanismo": {
"type": "string",
"description": "Mecanismo legal que autoriza a transferência (Art. 33)."
}
},
"additionalProperties": false,
"if": {
"properties": { "transfere": { "const": true } }
},
"then": {
"required": ["transfere", "destinos", "mecanismo"]
}
},
"scripts_terceiros": {
"type": "array",
"description": "Declaração de scripts de terceiros carregados no site.",
"items": {
"type": "object",
"required": ["nome", "finalidade", "consentimento_necessario"],
"properties": {
"nome": {
"type": "string",
"description": "Nome do serviço/script de terceiro."
},
"finalidade": {
"type": "string",
"description": "Finalidade do script (ex: analytics, marketing, cdn/segurança)."
},
"consentimento_necessario": {
"type": "boolean",
"description": "Se o script requer consentimento prévio do titular."
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}
O que o schema valida
Não é só verificar se os campos existem. O schema checa:
- • Tipos — string, boolean, array, object nos lugares certos
- • Formatos — CNPJ com regex, datas ISO 8601, e-mails válidos
- • Enums — bases legais e direitos restritos aos valores da LGPD
- • Obrigatoriedade — campos que não podem faltar em nenhum cenário
- • additionalProperties: false — rejeita campos inventados (typos viram erros)