Pular para o conteúdo

consent-record

privacy specs/privacy/consent-record.kmd

Corpo da especificação

Cookie / tracking consent-record contract

Status

Draft v0.1.0 — written 2026-06-02 alongside WEBKIT-034 (GDPR) + WEBKIT-036 (LGPD). Reference implementation: engines/sdk/koder_web_kit window.KoderConsent + <koder-cookie-banner>.

Scope

Defines the client-side consent record every Koder web surface (landing, Hub, web app) persists when a visitor makes a cookie/tracking choice, plus the rules that govern when the consent UI shows and how non-essential data collection (analytics, marketing) gates on it.

This is the web tracking-consent contract. It is distinct from identity/consent.kmd (server-side Scoped Consent Tokens — signed JWTs for sensitive ops like voice-clone), which is unrelated. Retention of any server-persisted consent records follows policies/identity-data-retention.kmd (LGPD Art. 15-16 / GDPR Art. 5(1)(e)).

Record shape

Persisted at localStorage["koder.consent"] as JSON:

{
  "v": 1,
  "policyVersion": "1",
  "ts": "2026-06-02T18:00:00.000Z",
  "locale": "pt-BR",
  "method": "accept-all | reject-all | custom",
  "categories": { "necessary": true, "analytics": false, "marketing": false }
}
  • v — record schema version (this contract); bump on a breaking shape change.
  • policyVersion — the site's consent-policy version; re-prompt on change (R3).
  • ts — ISO-8601 timestamp the choice was recorded.
  • locale<html lang> at record time.
  • method — how the choice was made.
  • categories — per-category booleans; necessary is always true.

Categories

CategoryGated?Meaning
necessarynever (always true)Required for the site to work.
analyticsyes (opt-in)Usage measurement.
marketingyes (opt-in)Personalisation / measurement.

Surfaces MAY define additional opt-in categories; necessary is reserved and always allowed.

Rules

  • R1 — Opt-in, default-deny. Until a record exists, only necessary is allowed. KoderConsent.allows(cat) MUST return false for any non-necessary category absent an explicit opt-in. No analytics/marketing script may run before consent (LGPD/GDPR lawful basis).
  • R2 — Reject as easy as accept. The first-tier banner MUST offer "Reject all" with the same prominence as "Accept all" (no scrolling, no extra clicks) — ANPD guidance / GDPR. A granular second tier ("Manage") is offered alongside, not instead.
  • R3 — Re-show conditions. The consent UI re-appears when: (a) no record, (b) policyVersion differs from the surface's current value, or (c) the record is older than the surface's max-age-days (default 365). Per components/banners.kmd §R4, re-show conditions are documented here rather than left implicit.
  • R4 — Audit trail (optional). A surface MAY POST the record to a record-endpoint for a server-side audit log; the client record is the source of truth for gating. Server copies follow identity-data-retention.kmd.
  • R5 — Gating API. Consumers gate collection on window.KoderConsent.allows('<category>') and react to changes via the koder:consent-change window event (detail = the record).

Reference implementation

engines/sdk/koder_web_kit:

  • window.KoderConsentget / allows / needed / set / acceptAll / rejectAll / reset / subscribe.
  • <koder-cookie-banner policy-version max-age-days policy-href record-endpoint> — two-tier banner (R2) + granular dialog, localized (en/pt/es), emits koder:consent / koder:consent-change.