Docs / Start here
Configuration
Changeward reads changeward.yaml from $CHANGEWARD_CONFIG, or from the working directory or the nearest parent
that has one. changeward connect creates and updates it. Values support ${VAR} expansion, so keep secrets in
the environment.
targets:
app:
adapter: postgres
env: personal # personal | shared-dev | staging | prod | prod-restricted
dsn: ${APP_DATABASE_URL}
sensitive: ["users.email", "*.password", "payments.card_last4"]
options:
checkpoint_strategy: template
default_target: app
policy: changeward.policy.yaml # default: changeward.policy.yaml next to this file, else built-ins
store: .changeward/changeward.db # audit log and change records (SQLite); $CHANGEWARD_STORE
plan_ttl: 15m # plans older than this must be re-planned
approvals:
slack:
bot_token: ${SLACK_BOT_TOKEN} # interactive Approve/Reject (needs `changeward serve`)
channel: "#db-changes"
signing_secret: ${SLACK_SIGNING_SECRET}
users: { U012ABC: "user:alice" } # Slack user → Changeward identity (for separation of duties)
# webhook_url: ${SLACK_WEBHOOK} # notifications only
signals:
jev:
enabled: false # see policy.md: advisory, can only tighten decisions
telemetry:
otlp_endpoint: http://otel-collector:4318 # or $OTEL_EXPORTER_OTLP_ENDPOINT
headers: { authorization: "Bearer ${OTEL_TOKEN}" }
executor: # only for `changeward executor serve`
tokens:
- { name: alice, sha256: "…", roles: [propose] }
adapters: # out-of-process adapters (go-plugin gRPC)
mongo: { path: /usr/local/bin/changeward-adapter-mongo }
Use changeward targets to list targets, and changeward connect NAME … to add or replace one:
changeward connect NAME --adapter ADAPTER --env CLASS [--dsn DSN] [--option key=value …] [--sensitive t.c,…] [--default]
Target options by adapter
Postgres (--adapter postgres, the default)
| Option | Meaning |
|---|---|
dsn |
Connection string. Use a role that can read the catalog. Checkpoints need CREATEDB. |
checkpoint_strategy |
template (default; CREATE DATABASE … TEMPLATE, needs no other connections), dump (pg_dump/pg_restore), or neon |
pg_dump, pg_restore |
Binary paths; with pg_dump set, template falls back to a dump |
maintenance_db |
Database to connect to for checkpoint and restore (default postgres) |
allow_terminate |
true lets a personal target terminate other connections for a template checkpoint |
copy_from |
Source for branch create copies (e.g. a masked golden image) |
neon_project_id, neon_branch_id, neon_api_key |
Neon branching for checkpoints and branches (neon_api_key defaults to $NEON_API_KEY) |
neon_checkpoint |
lsn (default; restore to a point in time) or branch |
neon_preserve_on_restore |
false deletes the branch being replaced on restore |
show_values |
true shows row values in shared-dev plans. By default only personal shows values. Shared-dev shows keys only; staging and prod show hashed keys. |
MySQL (--adapter mysql)
dsn in the Go MySQL driver's format, e.g. user:pass@tcp(localhost:3306)/app. DML is planned in a
rolled-back InnoDB transaction. DDL is analysed statically, and DROP is soft-dropped.
Kubernetes (--adapter kubernetes)
| Option | Meaning |
|---|---|
context, kubeconfig |
Which cluster. Inside a pod, the service account is used. |
namespace |
Default namespace for manifests without one |
kubectl |
Binary path |
rollout_timeout |
How long verify waits for rollouts (e.g. 5m) |
The operation payload is YAML manifests: changeward exec --target cluster -f deploy.yaml.
Terraform / OpenTofu (--adapter terraform)
| Option | Meaning |
|---|---|
dir |
Working directory |
binary |
terraform (default) or tofu |
var_files |
Comma-separated -var-files |
stateful_types |
Extra resource types whose destruction loses data |
The payload is apply (default) or destroy.
Config files (--adapter configfile)
| Option | Meaning |
|---|---|
path |
The managed file |
preset |
nginx, traefik or haproxy: default test and reload commands |
test_cmd |
Validates the candidate, without reloading (may use {file}) |
reload_cmd |
Reloads the service |
health_urls |
Comma-separated URLs that must answer 2xx/3xx after the reload. They are checked three times in a row; a failure rolls back. |
reload_settle |
Wait before health checks (default 700ms) |
The payload is the new file content.
HTTP APIs (--adapter httpapi)
| Option | Meaning |
|---|---|
base_url |
API base URL |
manifest |
Compensation manifest (e.g. manifests/github-issues.yaml) |
header.<Name> |
Request headers, e.g. header.Authorization: "Bearer ${GITHUB_TOKEN}" |
The payload is JSON: {"method": "PATCH", "path": "/repos/o/r/issues/3", "body": {…}}. Each manifest entry
declares:
match: method and path pattern;before: the read that captures the prior state;inverse: the undo call, templated with{param},{response.x},{body.x}and{before.x};reversibility;guard: fields compared for drift. The default is the fields the call writes or the inverse restores.
Calls with no matching entry are irreversible.
Environment variables
| Variable | Meaning |
|---|---|
CHANGEWARD_CONFIG, CHANGEWARD_STORE, CHANGEWARD_POLICY |
Override file locations |
CHANGEWARD_AGENT |
Marks the process as an agent: hooks and the MCP server set it, and approvals are refused when it's set |
CHANGEWARD_USER |
Your identity, if not your OS user |
CHANGEWARD_SESSION |
The current session |
CHANGEWARD_EXECUTOR_URL, CHANGEWARD_EXECUTOR_TOKEN |
Use a shared executor |
CHANGEWARD_REHEARSAL_DSN |
Scratch server for rehearse |
CHANGEWARD_GITLAB_TOKEN |
GitLab notes, statuses and approvals in CI |
OTEL_EXPORTER_OTLP_ENDPOINT |
OpenTelemetry export |
TYPESAFE_API_KEY |
Jev signals and changeward sensitive suggest |
Sensitive columns
sensitive entries (table.column or *.column) are redacted in every plan and query result shown to an agent.
changeward sensitive suggest proposes entries from table and column names and types only, never values. It
uses Jev and needs $TYPESAFE_API_KEY.
Edit this page on GitHub · synced from 89c04c9