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/cliOr install globally:
bun add -g @openpolicy/cliCreate 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 generateA unified config (defineConfig()) generates all sections in one pass. Given the example above, this writes:
output/
privacy-policy.md
terms-of-service.mdPass options to customize the output:
openpolicy generate --format markdown,html --out ./src/policiesTo generate from a specific file:
openpolicy generate ./openpolicy.ts --format markdown,html --out ./src/policies| Option | Default | Description |
|---|---|---|
config | ./openpolicy.ts | Path to the policy config (positional). Falls back to ./policy.config.ts then ./terms.config.ts if not found. |
--format | markdown | Comma-separated list of output formats: markdown, html |
--out | ./output | Output directory |
--type | (auto-detected) | "privacy", "terms", or "cookie" — inferred from filename; ignored for unified configs |
--watch | false | Watch config files and regenerate on changes |
The output filename is determined by the policy type:
| Type | Output filename |
|---|---|
privacy | privacy-policy.md / privacy-policy.html |
terms | terms-of-service.md / terms-of-service.html |
cookie | cookie-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 markdownInit
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 termsPrivacy 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.tsValidate
Check a config for compliance issues without generating output:
openpolicy validate ./openpolicy.ts| Option | Default | Description |
|---|---|---|
config | ./policy.config.ts | Path to the policy config (positional) |
--jurisdiction | all | Jurisdiction 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:
legalBasisrequired; 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
disclaimersorlimitationOfLiabilityare missing - Warning if
acceptance.methodsis 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 gdprpackage.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"
}
}