Pular para o conteúdo

Especificação CDS v0.2.0

Status: Rascunho Emissor: SignedData.Org Licença: MIT Substitui: CDS v0.1.0

O Curated Data Standard (CDS) é um padrão aberto para distribuição de dados curados, assinados criptograficamente, em tempo real, a partir de fontes verificadas. A versão 0.2.0 converte todas as identidades — eventos, fontes, tipos de conteúdo — em URIs HTTP dereferenciáveis, tornando todo evento CDS um JSON-LD válido. Com essa mudança, todo evento CDS passa a ser Linked Data 5 estrelas: legível por máquina, licenciado abertamente, estruturado em um formato não proprietário, descrito usando padrões W3C, e ligado a dados de outras pessoas via URIs.

Propriedades chave de um evento CDS permanecem inalteradas:

  • Tipado — carrega uma URI content_type identificando o domínio e o schema
  • Assinado — assinatura RSA-PSS SHA-256 pelo produtor, verificável por qualquer consumidor
  • Fingerprintado — SHA-256 da resposta bruta da API upstream, provando que os bytes da fonte não foram alterados
  • Enriquecidocontext.summary opcional gerado por LLM no idioma declarado
  • Ligado — toda entidade é uma URI HTTP dereferenciável retornando JSON-LD (NOVO em v0.2.0)

O CDS v0.2.0 é projetado para satisfazer as quatro regras de Linked Data articuladas por Tim Berners-Lee.

Regra 1: Use URIs como nomes para coisas. O CDS nomeia toda entidade com uma URI. Eventos são identificados por https://signed-data.org/events/{uuid}, tipos de conteúdo por https://signed-data.org/vocab/{domain}/{schema} e fontes por https://signed-data.org/sources/{source-id}.

Regra 2: Use URIs HTTP para que pessoas possam consultar esses nomes. Todas as URIs CDS usam a base https://signed-data.org. Não são identificadores opacos — são URIs HTTPS que resolvem para endpoints reais na web.

Regra 3: Quando alguém consultar uma URI, forneça informação útil usando padrões. Toda URI CDS retorna um documento JSON-LD. URIs de fontes retornam metadados da fonte; URIs de tipo de conteúdo retornam definições de schema; a raiz do vocabulário retorna a ontologia completa.

Regra 4: Inclua links para outras URIs. Eventos CDS contêm links para outros recursos CDS — eventos para fontes para domínios para vocabulário, formando um grafo navegável.

Veja Linked Data para o aprofundamento.

O CDS v0.2.0 alcança a classificação máxima de 5 estrelas de dados abertos:

★ Available online under an open license ✓ (v0.1.0)
★★ Structured data (not a scanned image) ✓ (v0.1.0)
★★★ Non-proprietary format (JSON) ✓ (v0.1.0)
★★★★ Use open W3C standards (JSON-LD) ✓ NEW in v0.2.0
★★★★★ Link to other people's data (URI links) ✓ NEW in v0.2.0

Todo evento CDS v0.2.0 é um documento JSON-LD válido:

{
"@context": "https://signed-data.org/contexts/cds/v1.jsonld",
"@type": "https://signed-data.org/vocab/CuratedDataEvent",
"@id": "https://signed-data.org/events/a3f8c2d1-4e2b-4f8a-9c1d-2e3f4a5b6c7d",
"spec_version": "0.2.0",
"id": "a3f8c2d1-4e2b-4f8a-9c1d-2e3f4a5b6c7d",
"content_type": "https://signed-data.org/vocab/lottery-brazil/mega-sena-result",
"source": {
"@id": "https://signed-data.org/sources/caixa.gov.br.loterias.v1",
"fingerprint": "sha256:b310..."
},
"occurred_at": "2026-03-29T00:00:00Z",
"ingested_at": "2026-03-29T00:00:04Z",
"lang": "pt-BR",
"payload": { },
"context": {
"summary": "Mega Sena concurso 2800...",
"model": "rule-based-v1",
"generated_at": "2026-03-29T00:00:05Z"
},
"integrity": {
"hash": "sha256:a1b2c3...",
"signature": "MX6rj3...",
"signed_by": "https://signed-data.org"
}
}

Os campos @context, @type e @id DEVEM aparecer primeiro na saída serializada. O campo id (UUID puro) é mantido junto com @id (URI completa) por conveniência.

Campov0.1.0v0.2.0Mudança
@contextausente"https://signed-data.org/contexts/cds/v1.jsonld"novo
@typeausente"https://signed-data.org/vocab/CuratedDataEvent"novo
@idausente"https://signed-data.org/events/{uuid}"novo
spec_version"0.1.0""0.2.0"atualizado
content_typeobjeto CDSContentTypestring URIbreaking
source.idstring opacaausenteremovido
source.@idausenteURI HTTPsubstitui source.id
integrity.signed_by"signed-data.org""https://signed-data.org"breaking

Todas as URIs CDS compartilham a base https://signed-data.org.

RecursoPadrãoExemplo
Evento/events/{uuid}https://signed-data.org/events/a3f8c2d1-...
Tipo de conteúdo/vocab/{domain-slug}/{schema-slug}.../vocab/lottery-brazil/mega-sena-result
Fonte/sources/{source-id}.../sources/caixa.gov.br.loterias.v1
Raiz do vocabulário/vocab/https://signed-data.org/vocab/
Contexto JSON-LD/contexts/cds/v1.jsonld.../contexts/cds/v1.jsonld
Chave pública/.well-known/cds-public-key.pem.../cds-public-key.pem

Slugs de domínio: pontos no nome do domínio viram hifens. lottery.brazillottery-brazil. sports.footballsports-football.

Slugs de schema: pontos no nome do schema viram hifens. mega-sena.resultmega-sena-result.

IDs de fonte: pontos são mantidos como estão. caixa.gov.br.loterias.v1 continua caixa.gov.br.loterias.v1.

https://signed-data.org/vocab/{domain-slug}/{schema-slug}

A assinatura da função construtora é content_type_uri(domain, schema_name) — ambos os argumentos usam a notação original com pontos.

ConstanteURI
LOTTERY_MEGA_SENA.../vocab/lottery-brazil/mega-sena-result
LOTTERY_LOTOFACIL.../vocab/lottery-brazil/lotofacil-result
LOTTERY_QUINA.../vocab/lottery-brazil/quina-result
LOTTERY_LOTOMANIA.../vocab/lottery-brazil/lotomania-result
LOTTERY_DUPLA_SENA.../vocab/lottery-brazil/dupla-sena-result
ConstanteURI
FOOTBALL_MATCH_RESULT.../vocab/sports-football/match-result
FOOTBALL_MATCH_LIVE.../vocab/sports-football/match-live
FOOTBALL_STANDINGS.../vocab/sports-football/standings-update
ConstanteURI
WEATHER_CURRENT.../vocab/weather/forecast-current
WEATHER_DAILY.../vocab/weather/forecast-daily
WEATHER_ALERT.../vocab/weather/alert-severe
ConstanteURI
FINANCE_STOCK.../vocab/finance/quote-stock
FINANCE_CRYPTO.../vocab/finance/quote-crypto
FINANCE_FOREX.../vocab/finance/quote-forex
FINANCE_INDEX.../vocab/finance/index-update

Veja a especificação do domínio finance.brazil para os tipos de conteúdo completos das finanças brasileiras.

Uma fonte representa um provedor upstream de dados verificado. Cada fonte é identificada por uma URI da forma https://signed-data.org/sources/{source-id}.

Dereferenciar uma URI de fonte retorna um documento JSON-LD:

{
"@context": "https://signed-data.org/contexts/cds/v1.jsonld",
"@type": "https://signed-data.org/vocab/DataSource",
"@id": "https://signed-data.org/sources/caixa.gov.br.loterias.v1",
"name": "Caixa Econômica Federal — Loterias",
"domain": "caixa.gov.br",
"version": "v1",
"upstream": "https://servicebus2.caixa.gov.br/portaldeloterias/api/megasena",
"content_types": [
"https://signed-data.org/vocab/lottery-brazil/mega-sena-result",
"https://signed-data.org/vocab/lottery-brazil/lotofacil-result"
]
}
ConstanteURI da fonte
CAIXA_LOTERIAS.../sources/caixa.gov.br.loterias.v1
API_FOOTBALL.../sources/api-football.com.v3
OPEN_METEO.../sources/open-meteo.com.v1
BRAPI.../sources/brapi.dev.v1
BCB_SGS.../sources/api.bcb.gov.br.v1
CONAB.../sources/conab.gov.br.v1
WORLD_BANK.../sources/api.worldbank.org.v2
BRASILAPI.../sources/brasilapi.com.br.v1

A ontologia CDS é publicada em https://signed-data.org/vocab/. Define as classes e propriedades usadas em eventos CDS.

ClasseURIDescrição
CuratedDataEvent.../vocab/CuratedDataEventO envelope de evento de nível superior
IntegrityMeta.../vocab/IntegrityMetaProva criptográfica anexada a um evento
DataSource.../vocab/DataSourceUm provedor upstream de dados registrado
PropriedadeURIDomínioRange
specVersion.../vocab/specVersionCuratedDataEventxsd:string
contentType.../vocab/contentTypeCuratedDataEventURI
source.../vocab/sourceCuratedDataEventDataSource
occurredAt.../vocab/occurredAtCuratedDataEventxsd:dateTime
ingestedAt.../vocab/ingestedAtCuratedDataEventxsd:dateTime
lang.../vocab/langCuratedDataEventxsd:string
payload.../vocab/payloadCuratedDataEventobjeto JSON
context.../vocab/contextCuratedDataEventobjeto JSON
hash.../vocab/hashIntegrityMetaxsd:string
signature.../vocab/signatureIntegrityMetaxsd:string
signedBy.../vocab/signedByIntegrityMetaURI
fingerprint.../vocab/fingerprintDataSourcexsd:string
  1. Serialize para JSON canônico — sort_keys=True, UTF-8, excluindo integrity e ingested_at
  2. hash = "sha256:" + SHA256(canonical_bytes).hexdigest()
  3. Assine canonical_bytes com RSA-PSS (digest SHA-256, MGF1, tamanho de salt máximo)
  4. Codifique a assinatura como base64
  5. Anexe IntegrityMeta { hash, signature, signed_by }

Verificação: re-serialize os bytes canônicos, verifique o hash, verifique a assinatura RSA-PSS com a chave pública do emissor publicada em https://signed-data.org/.well-known/cds-public-key.pem.

Para detalhes completos, veja Assinatura.

O @context em https://signed-data.org/contexts/cds/v1.jsonld mapeia as chaves JSON snake_case usadas pelo CDS para predicados RDF:

{
"@context": {
"@vocab": "https://signed-data.org/vocab/",
"spec_version": "specVersion",
"content_type": { "@id": "contentType", "@type": "@id" },
"source": { "@id": "source", "@type": "@id" },
"occurred_at": "occurredAt",
"ingested_at": "ingestedAt",
"signed_by": { "@id": "signedBy", "@type": "@id" },
"fingerprint": "fingerprint",
"lang": "lang",
"payload": "payload",
"context": "context",
"hash": "hash",
"signature": "signature",
"integrity": "integrity"
}
}

Isso atinge dois objetivos simultaneamente:

  1. Consumidores de JSON puro não são afetados. Um consumidor que ignora @context, @type e @id lê todos os outros campos exatamente como antes. Sem necessidade de biblioteca JSON-LD.
  2. Consumidores RDF obtêm triplas válidas. Um processador JSON-LD expande qualquer evento CDS em um grafo RDF. Campos tipados como @id produzem links RDF apropriados.

12. Mudanças incompatíveis em relação à v0.1.0

Seção intitulada “12. Mudanças incompatíveis em relação à v0.1.0”
Mudançav0.1.0v0.2.0Impacto
Tipo do campo content_typeobjeto CDSContentTypestring URITodo código que lê content_type.domain precisa mudar
source.id renomeado para source.@idstring opacaURI HTTPMudança de chave JSON; use os helpers do SDK
integrity.signed_by"signed-data.org""https://signed-data.org"Comparação de string vai quebrar
Bytes canônicosExcluir integrity, ingested_atMesmas exclusões, mas inclui @context, @type, @idAssinaturas v0.1.0 não podem ser verificadas por verificadores v0.2.0
Novos campos obrigatóriosN/D@context, @type, @idProdutores devem incluir esses campos

Para exemplos de código de migração, veja Migração v0.1 → v0.2.