Reference
Validation & Schemas
Declare project-wide and environment-specific rules, validate encrypted or local values, and keep configuration contracts reviewable in Git.
Schema files
Global rules live in .ghostable/schema.yaml. Rules for one environment live in .ghostable/schemas/<environment>.yaml. Both are plaintext, repository-visible contracts and must not include secret values.
Schema format
APP_ENV:
- required
- in:local,staging,production
APP_URL:
- required
- url
- starts_with:https://
QUEUE_CONNECTION:
- nullable
- string
SESSION_LIFETIME:
- required
- integer
- min:1
- max:1440
Each top-level key maps to a list of rules. Rules with arguments use name:argument. The presence of nullable skips other rules for a missing or empty value regardless of where it appears in the list; required still wins when both are present.
Supported rules
-
required - The key must exist and have a non-empty value.
-
nullable - Other rules are skipped when the value is missing or empty.
-
string - Accepts the env value as a string.
-
integer / numeric - Requires an integer or floating-point-compatible numeric value.
-
boolean - Accepts true, false, 1, 0, yes, or no, case-insensitively.
-
email / url - Requires a valid email address or absolute URL.
-
starts_with / ends_with - Requires the declared prefix or suffix.
-
regex - Requires a match against a Go RE2-compatible expression. Use the schema command to avoid hand-escaping YAML.
-
in - Requires one of a comma-separated set of exact values.
-
min / max - Compares parseable numeric values numerically and other values by UTF-8 byte length.
-
different_from - Compares the same key against stored values in another environment. It passes when that environment has no matching key.
REGION:
- required
- 'regex:^[A-Z]{2}$'
API_KEY:
- required
- min:32
- different_from:staging
In this example, REGION=US passes while REGION=us fails. API_KEY must be at least 32 bytes and must not equal the stored API_KEY in staging.
Environment-specific rules
Environment rules are appended to global rules for the same key. This makes it possible to keep a shared contract while adding production requirements:
# .ghostable/schemas/production.yaml
APP_KEY:
- required
- different_from:staging
APP_DEBUG:
- required
- in:false,0
Manage schemas
$ ghostable schema rule add --key APP_URL --rule required
$ ghostable schema rule add --key APP_URL --rule url
$ ghostable schema rule update --key APP_URL --old-rule url --new-rule starts_with:https://
$ ghostable schema rule remove --key APP_URL --rule starts_with:https://
$ ghostable schema key rename --old-key OLD_API_URL --new-key API_URL
Pass --file .ghostable/schemas/production.yaml to target an environment-specific schema.
Run validation
$ ghostable validate --env production
$ ghostable validate --env staging --file .env.staging
$ ghostable validate --env production --json
Without --file, validation reads stored encrypted values. With --file, it validates that local file against the selected environment's merged rules. A warning is emitted when no schema rules exist.
A different_from rule still reads the referenced environment even during file validation. If that environment is protected, the local device must satisfy user-presence verification; automation needs a credential with reader access to both environments.