ePrivacy Art. 5(3) requires informed consent before accessing device storage — users cannot give informed consent to cookies they don't know exist. GDPR Art. 13 requires controllers to disclose the categories of data processed and the recipients, which for cookie-based tracking means naming every third-party tool and the cookies it sets. CCPA §1798.135 requires disclosure of the categories of personal information collected and shared. An undocumented cookie from Hotjar or a Facebook Pixel is not a minor oversight — it is an undisclosed collection of behavioral data shared with a third-party processor outside the scope of any consent obtained.
High because undocumented cookies represent undisclosed data collection, directly violating the transparency obligations of GDPR Art. 13 and the informed-consent prerequisite of ePrivacy Art. 5(3).
Create a central COOKIE_REGISTRY constant and drive both the consent banner and the cookie policy page from it. Add an entry every time a new third-party script is added to the project.
// src/lib/cookies/registry.ts
export const COOKIE_REGISTRY: CookieEntry[] = [
{
name: 'session',
category: 'essential',
purpose: 'Maintains authenticated user session.',
expiry: 'Session',
provider: 'First party',
thirdParty: false,
},
{
name: '_ga, _ga_XXXXXXXX',
category: 'analytics',
purpose: 'Google Analytics — tracks page views pseudonymously.',
expiry: '2 years',
provider: 'Google LLC',
thirdParty: true,
},
{
name: '_fbp',
category: 'marketing',
purpose: 'Facebook Pixel — ad conversion attribution.',
expiry: '90 days',
provider: 'Meta Platforms Inc.',
thirdParty: true,
},
]
Run a comparison between this registry and document.cookie values in staging to detect gaps before shipping new third-party integrations.
ID: cookie-consent-compliance.cookie-classification.all-cookies-documented
Severity: high
What to look for: Build a complete inventory of cookies and tracking technologies the application sets. Gather from: (1) document.cookie = in client-side code, (2) Set-Cookie headers in server-side API routes, (3) third-party scripts that set their own cookies (GA4 sets _ga, _ga_XXXXXXXX; Facebook Pixel sets _fbp, _fbc; Hotjar sets _hjid, _hjFirstSeen). Cross-reference this inventory against a cookie registry in the codebase — a TypeScript constant, a JSON file, or a consent platform configuration. A cookie is "documented" when it has: a name (or name pattern), a category (essential/analytics/marketing/preferences), a human-readable purpose, and a duration/expiry. Compare the two lists. Are there cookies the application sets that are not in the registry? Are there registry entries for cookies the application no longer sets?
Pass criteria: Enumerate all cookies set by the site (including third-party). A cookie registry exists and is complete. Every cookie and tracking technology the application sets (first-party and third-party via loaded scripts) appears in the registry with its name, category, purpose, and expiry. The registry is current (no orphaned entries for removed cookies). 100% of cookies must be documented in the cookie policy. Report the count of documented vs undocumented cookies even on pass.
Fail criteria: Quote the undocumented cookie names found. No cookie registry found anywhere (not in code, not in the consent platform config, not in the privacy/cookie policy). Registry exists but is incomplete — some cookies set by loaded third-party scripts are not documented. Registry exists but is outdated (lists cookies the application no longer sets; missing cookies it does set).
Skip (N/A) when: Application sets no cookies at all — not even session cookies — and loads no third-party scripts.
Detail on fail: Specify what is missing. Example: "No cookie registry found. Application sets _ga, _ga_XXXXXXXX (GA4), _fbp (Facebook Pixel), and session cookie but none are documented in a cookie register." or "Cookie policy lists only 3 cookies but application loads Hotjar which sets _hjid and _hjFirstSeen — these are undocumented.".
Remediation: Create a central cookie registry and keep it as the source of truth for both the consent banner and the cookie policy page:
// lib/cookies/registry.ts
export type CookieCategory = 'essential' | 'analytics' | 'marketing' | 'preferences'
export type CookieEntry = {
name: string // exact name or pattern (e.g., "_ga_*")
category: CookieCategory
purpose: string // human-readable, used in cookie policy
expiry: string // "Session", "1 year", "90 days", etc.
provider: string // "First party" or vendor name
thirdParty: boolean
}
export const COOKIE_REGISTRY: CookieEntry[] = [
{
name: 'session',
category: 'essential',
purpose: 'Maintains authenticated user session. Required for login to function.',
expiry: 'Session',
provider: 'First party',
thirdParty: false,
},
{
name: '__Host-csrf',
category: 'essential',
purpose: 'Prevents cross-site request forgery attacks.',
expiry: 'Session',
provider: 'First party',
thirdParty: false,
},
{
name: '_ga, _ga_XXXXXXXX',
category: 'analytics',
purpose: 'Google Analytics — tracks page views and user journeys pseudonymously.',
expiry: '2 years',
provider: 'Google LLC',
thirdParty: true,
},
{
name: '_fbp',
category: 'marketing',
purpose: 'Facebook Pixel — tracks conversion events for ad attribution.',
expiry: '90 days',
provider: 'Meta Platforms Inc.',
thirdParty: true,
},
]
Import this registry into your consent banner (to display category descriptions) and your cookie policy page (to render the per-cookie table). Add an entry every time you add a new third-party script.
Cross-reference: For per-cookie documentation details, see the per-cookie-documentation check in the Cookie Transparency category below.