Consent ceremony

Pro

Consent that names exactly what flows where (Candor's CeremonySurface): each flow as what → where → how long it's kept, an acknowledgement the person ticks themselves, and how to take it back. The grant button stays locked, with its reason, until they've ticked it.

Markdown

Preview

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/consent-ceremony

Brings in: button, locale, locked, team, terms, utils · npm: lucide-react@^1.67.0

Usage

TSX · The example above
"use client"

import { ConsentCeremony } from "@/components/consent-ceremony"
import type { DataFlow } from "@/lib/team"

const flows: DataFlow[] = [
  { what: "Code and config: repositories, schema, migrations and CI settings", to: "Keel’s servers in us-east", kept: "while connected" },
  { what: "Row counts and column fill rates", to: "Keel’s servers in us-east", kept: "90 days" },
  { what: "What an agent needs to answer a question", to: "The model provider, with zero data retention", kept: "not kept after the answer" },
]

export default function Example() {
  return (
    <ConsentCeremony
      className="w-full max-w-xl"
      title="Allow Keel to read Acme API Staging"
      flows={flows}
      notFlowing={["Row contents, unless an agent needs one to answer you", "Secrets, environment variables and encrypted columns"]}
      revoke="Disconnect in Settings › Environments. Access stops at once."
      acknowledgement="I can connect this code for Acme, and I understand what Keel reads and where it goes."
      grantLabel="Allow and continue"
      onGrant={() => {}}
      onCancel={() => {}}
    />
  )
}

<ConsentCeremony>

PropTypeDefaultDescription
titlerequiredstring—The heading, e.g. "Let agents read your workspace".
flowsrequiredDataFlow[]—Each thing read: what it is, where it goes and how long it's kept.
notFlowingstring[] | undefined—What does not leave, said plainly.
revokerequiredstring—How to revoke later.
acknowledgementrequiredstring—The sentence the person ticks themselves before granting.
grantLabelstring | undefined—The grant button's label. Defaults to "Allow".
onGrantrequired() => void—Called when the person grants, after ticking the acknowledgement.
onCancel(() => void) | undefined—Shows Not now; called when it's clicked.
busyboolean | undefinedfalseDisables the grant button while consent is being recorded.
classNamestring | undefined—Extra classes for the outer element.

Strings

The fixed words, in English by default. Change any of them under consentCeremony in <LocaleProvider strings={{ … }}>; the table is exported as consentCeremonyStrings.

KeyEnglish
allowAllow
whatIsReadWhat {product} will read, and where it goes
goesTogoes to
keptKept: {kept}
whatStaysWhat stays in your {environment}
takeBackTo take this back:
notNowNot now
tickFirstTick the acknowledgement first.