First step of the .zddc-first-configuration rollout: pure plumbing
that makes the future move-everything-out-of-Go work mechanically
possible without changing any current behaviour.
New pieces:
1. zddc/internal/zddc/defaults.zddc.yaml — a real YAML file in the
repo. Single source of truth for the baked-in baseline; intentionally
minimal in Phase 1 (just title + empty acl) so existing deployments
stay bit-identical until Phase 2 starts populating the schema.
2. //go:embed (defaults.go) bakes the bytes into the binary so
shipped deployments don't need the file. Operators who want a
starting point export with:
zddc-server show-defaults > /var/lib/zddc/root/.zddc
3. PolicyChain gains an Embedded ZddcFile field. EffectivePolicy
layers in the embedded defaults as a baseline below the on-disk
chain. Consumers that want the full effective view consult both;
existing consumers that only read chain.Levels keep working
bit-identically (the new field is additive).
4. New top-level `inherit:` key on ZddcFile. Default true. Set
`inherit: false` on any on-disk .zddc to zero out chain.Embedded
— the operator owns every rule from that level outward. Useful at
the on-disk root to fully reject the embedded defaults; useful at
deeper levels for sandbox subtrees.
5. `zddc-server show-defaults` (also accepts --show-defaults) subcommand
dumps the embedded bytes to stdout — same shape as --print-rego.
No flag plumbing needed beyond the existing args walk.
6. Tests: parse-roundtrip on the embedded file, presence in chain by
default, inherit:false drops it, explicit inherit:true is a no-op
versus the default.
Phase 2 (next): add a `paths:` recursive map + `default_tool:` /
`auto_own:` / `virtual:` keys, populate defaults.zddc.yaml with the
canonical ZDDC convention, and migrate apps.DefaultAppAt /
AutoOwnCanonicalNames / VirtualOnlyCanonicalNames to cascade lookups.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
40 lines
1.1 KiB
Go
40 lines
1.1 KiB
Go
package zddc
|
|
|
|
import (
|
|
_ "embed"
|
|
"sync"
|
|
)
|
|
|
|
// defaultsBytes is the embedded baseline .zddc — see defaults.zddc.yaml
|
|
// for the source-of-truth and a description of its role in the cascade.
|
|
//
|
|
//go:embed defaults.zddc.yaml
|
|
var defaultsBytes []byte
|
|
|
|
// EmbeddedDefaultsBytes returns the raw embedded defaults YAML.
|
|
//
|
|
// Surface: the show-defaults CLI subcommand dumps these bytes to
|
|
// stdout so operators can copy them into <ZDDC_ROOT>/.zddc and edit.
|
|
func EmbeddedDefaultsBytes() []byte {
|
|
out := make([]byte, len(defaultsBytes))
|
|
copy(out, defaultsBytes)
|
|
return out
|
|
}
|
|
|
|
var (
|
|
embeddedDefaultsOnce sync.Once
|
|
embeddedDefaults ZddcFile
|
|
embeddedDefaultsErr error
|
|
)
|
|
|
|
// EmbeddedDefaults returns the parsed embedded defaults ZddcFile,
|
|
// memoised. Parse errors surface on the first call and are sticky.
|
|
//
|
|
// The cascade walker (EffectivePolicy) consults this as the bottom-
|
|
// most level unless an on-disk .zddc up the chain sets `inherit: false`.
|
|
func EmbeddedDefaults() (ZddcFile, error) {
|
|
embeddedDefaultsOnce.Do(func() {
|
|
embeddedDefaults, embeddedDefaultsErr = parseBytes(defaultsBytes)
|
|
})
|
|
return embeddedDefaults, embeddedDefaultsErr
|
|
}
|