OpenPolicy
Generative

CLI

Using OpenPolicy with the CLI

The @openpolicy/cli package provides the openpolicy command for generating and validating policy documents without a build tool.

Installation

bun add -D @openpolicy/cli

Or install globally:

bun add -g @openpolicy/cli

Create your config

Create an openpolicy.ts at the root of your project using defineConfig() from @openpolicy/sdk:

// openpolicy.ts
import { defineConfig } from "@openpolicy/sdk";

export default defineConfig({
  company: {
    name: "Acme Inc.",
    legalName: "Acme Corporation",
    address: "123 Main St, Springfield, USA",
    contact: "privacy@acme.com",
  },
  privacy: {
    effectiveDate: "2026-01-01",
    dataCollected: {
      "Account Information": ["Name", "Email address"],
      "Usage Data": ["Pages visited", "Browser type", "IP address"],
    },
    legalBasis: "Legitimate interests and consent",
    retention: { "Account data": "Until account deletion" },
    cookies: { essential: true, analytics: false, marketing: false },
    thirdParties: [],
    userRights: ["access", "erasure"],
    jurisdictions: ["us", "eu"],
  },
  terms: {
    effectiveDate: "2026-01-01",
    acceptance: { methods: ["using the service", "creating an account"] },
    governingLaw: { jurisdiction: "Delaware, USA" },
  },
});

See the openpolicy.ts reference → for all available fields.

Generate

Run openpolicy generate with no arguments — it looks for openpolicy.ts automatically and compiles every section present:

openpolicy generate

A unified config (defineConfig()) generates all sections in one pass. Given the example above, this writes:

output/
  privacy-policy.md
  terms-of-service.md

Pass options to customize the output:

openpolicy generate --format markdown,html --out ./src/policies

To generate from a specific file:

openpolicy generate ./openpolicy.ts --format markdown,html --out ./src/policies
OptionDefaultDescription
config./openpolicy.tsPath to the policy config (positional). Falls back to ./policy.config.ts then ./terms.config.ts if not found.
--formatmarkdownComma-separated list of output formats: markdown, html
--out./outputOutput directory
--type(auto-detected)"privacy", "terms", or "cookie" — inferred from filename; ignored for unified configs
--watchfalseWatch config files and regenerate on changes

The output filename is determined by the policy type:

TypeOutput filename
privacyprivacy-policy.md / privacy-policy.html
termsterms-of-service.md / terms-of-service.html
cookiecookie-policy.md / cookie-policy.html

Type auto-detection: if the config filename contains "cookie" it's treated as a cookie policy, "terms" as terms of service, otherwise privacy. Use --type to override.

Examples

# Unified config — generates all sections (default)
openpolicy generate

# Both formats into src/policies
openpolicy generate --format markdown,html --out ./src/policies

# Watch mode — regenerate on config changes
openpolicy generate --format html --out ./src/policies --watch

# Explicit type override for a non-standard filename
openpolicy generate ./my.config.ts --type terms --format markdown

Init

The init command runs an interactive wizard and writes a ready-to-use config file for a single policy type:

# Privacy policy wizard (default)
openpolicy init

# Terms of service wizard
openpolicy init --type terms

Privacy policy wizard prompts for:

  • Company name and legal entity name
  • Company address and privacy contact email
  • Jurisdiction (GDPR, CCPA, or both)
  • Data categories collected
  • Whether your app uses cookies

Terms of service wizard prompts for:

  • Company name and legal entity name
  • Company address and legal contact email
  • Governing law jurisdiction

The output path defaults to ./privacy.config.ts or ./terms.config.ts based on --type. Override with --out:

openpolicy init --type terms --out ./openpolicy.ts

Validate

Check a config for compliance issues without generating output:

openpolicy validate ./openpolicy.ts
OptionDefaultDescription
config./policy.config.tsPath to the policy config (positional)
--jurisdictionallJurisdiction to validate against: gdpr, ccpa, or all (privacy only)
--type(auto-detected)"privacy", "terms", or "cookie" — inferred from filename if omitted

Privacy policy validation checks:

  • Required fields: effectiveDate, company.*, dataCollected
  • GDPR: legalBasis required; recommended user rights (access, rectification, erasure, portability, restriction, objection)
  • CCPA: recommended user rights (access, erasure, opt_out_sale, non_discrimination)

Terms of service validation checks:

  • Required fields: effectiveDate, company.*, governingLaw.jurisdiction
  • Warnings if disclaimers or limitationOfLiability are missing
  • Warning if acceptance.methods is empty

Errors cause a non-zero exit code. Warnings are printed but do not fail the process.

# Check GDPR compliance only
openpolicy validate ./openpolicy.ts --jurisdiction gdpr

package.json scripts

A common pattern is to add a generate:policy script that runs before your build:

{
  "scripts": {
    "generate:policy": "openpolicy generate --format markdown,html --out ./src/policies",
    "build": "bun run generate:policy && next build"
  }
}

On this page