Add explicit secrets directory bootstrap
This commit is contained in:
@@ -144,6 +144,41 @@ configuration values. Applications must still keep source labels, resolution
|
||||
reasons, and diagnostic messages value-free because ConfigKit cannot infer and
|
||||
sanitize secrets embedded in arbitrary application prose.
|
||||
|
||||
## Explicit secrets-directory bootstrap
|
||||
|
||||
`LoadSecretsDir(directory)` is a separate, opt-in startup operation. It is never
|
||||
called by `Load`, is not a YAML option, and does not participate in configuration
|
||||
validation. Applications choose the native directory path and should invoke the
|
||||
operation once before starting concurrent work. The selected path may itself be a
|
||||
symlink; ConfigKit resolves it to an existing canonical directory before examining
|
||||
its immediate entries.
|
||||
|
||||
The bootstrap enumerates at most 1,024 entries and sorts them by filename. Every
|
||||
entry must have an ASCII environment-variable name and be a regular, nonsymlink
|
||||
file. Metadata for all entries is validated before file content is read or process
|
||||
state is changed. Existing environment variables win, including variables whose
|
||||
value is empty; their files are not opened. Each eligible file is limited to 1 MiB,
|
||||
and eligible content is limited to 8 MiB in total. ConfigKit removes exactly one
|
||||
terminal LF or CRLF, preserves all other whitespace, accepts an empty value, and
|
||||
rejects NUL bytes.
|
||||
|
||||
All eligible files are read successfully before application begins. Presence is
|
||||
checked again immediately before each `os.Setenv`: a variable populated since
|
||||
preflight is skipped. A write failure stops application without rollback, so prior
|
||||
writes remain and later eligible entries are `not_applied`. This operation is not
|
||||
atomic and does not provide compare-and-set semantics for concurrent environment
|
||||
mutation.
|
||||
|
||||
`SecretsReport.Entries` returns detached, filename-ordered `SecretFileResult`
|
||||
records with `loaded`, `skipped_existing`, `not_applied`, or `failed` status.
|
||||
`ExistingEmpty` distinguishes an empty existing winner. `SecretsReport.WriteTo`
|
||||
renders only quoted names, canonical paths, statuses, and that empty-state flag;
|
||||
it never retains or renders file contents. Failures return the non-nil partial
|
||||
report with a `*SecretsError` containing detached `secrets.*` diagnostics and no
|
||||
raw filesystem or environment error chain. Applications should retain the report
|
||||
alongside the later configuration result and explicitly present blocked and failed
|
||||
files when appropriate; ConfigKit stores no implicit global report.
|
||||
|
||||
### Recorded application resolution
|
||||
|
||||
An optional `Definition.Resolve` callback runs after successful typed decoding. It
|
||||
|
||||
Reference in New Issue
Block a user