Problem
targets/*.yml now supports app_refs (a list) to assemble a target's app
catalog from multiple independent bundles/repos. env_ref is still a single
ref — there's no equivalent way to compose a target's env vars from more
than one encrypted vault source, even though the same "compose config from
multiple independent repos" motivation applies to secrets/env as much as it
does to apps.
Why this isn't just "make it a list"
Unlike apps (file-based, namespaced by directory name, trivially
conflict-checked), merging multiple decrypted .sops.env sources has real
obstacles:
APPS= is a generated aggregate, not a plain field. Each vault
manifest renders its own APPS=... line from its own apps: list.
Naively concatenating multiple decrypted .env files means the last
APPS= line wins (dotenv parsing is last-value-wins on duplicate keys) —
apps merged into apps/ via app_refs from earlier sources would
silently never start, because they'd have dropped out of the effective
APPS= value. Merging env sources correctly requires explicitly
unioningAPPS= across all contributing vaults, not just concatenating
files.- Cross-repo encryption-recipient coordination.
env_ref points at a
SOPS-encrypted asset, encrypted for a specific set of age recipients
(keys: in the vault manifest). For a third-party repo to contribute env
vars to the same target, its author needs the target server's public age
key (keys/hawkeye.pub today lives only in this repo) ahead of time and
must explicitly encrypt for it. There's no existing mechanism for
sharing/publishing that public key across repos. app_refs has no
equivalent problem since app bundles aren't per-recipient encrypted. - Ordinary key collisions (two sources both define, say,
APPS_TIMEZONE) also need an explicit policy — silently overwrite, or
fail loud like the existing app-name-conflict check in
ansible/deploy.yml.
Proposed direction (not designed yet)
env_refs (list, mirroring app_refs) in targets/*.yml.ansible/deploy.yml (or a new step) decrypts each source, unions the
apps: lists before rendering APPS= (or unions the already-rendered
APPS= values), and fails loud on any other key collision across sources
— matching the existing app-conflict philosophy instead of introducing
silent overwrite behavior.- Cross-repo key sharing needs its own decision — publish
keys/*.pub as a
discoverable asset/convention, or require the target repo owner to hand
out the pubkey out-of-band.
Related
Surfaced during final review of #102, same session as #103 (ansible
ref-resolution dedup).
Problem
targets/*.ymlnow supportsapp_refs(a list) to assemble a target's appcatalog from multiple independent bundles/repos.
env_refis still a singleref — there's no equivalent way to compose a target's env vars from more
than one encrypted vault source, even though the same "compose config from
multiple independent repos" motivation applies to secrets/env as much as it
does to apps.
Why this isn't just "make it a list"
Unlike apps (file-based, namespaced by directory name, trivially
conflict-checked), merging multiple decrypted
.sops.envsources has realobstacles:
APPS=is a generated aggregate, not a plain field. Each vaultmanifest renders its own
APPS=...line from its ownapps:list.Naively concatenating multiple decrypted
.envfiles means the lastAPPS=line wins (dotenv parsing is last-value-wins on duplicate keys) —apps merged into
apps/viaapp_refsfrom earlier sources wouldsilently never start, because they'd have dropped out of the effective
APPS=value. Merging env sources correctly requires explicitlyunioning
APPS=across all contributing vaults, not just concatenatingfiles.
env_refpoints at aSOPS-encrypted asset, encrypted for a specific set of age recipients
(
keys:in the vault manifest). For a third-party repo to contribute envvars to the same target, its author needs the target server's public age
key (
keys/hawkeye.pubtoday lives only in this repo) ahead of time andmust explicitly encrypt for it. There's no existing mechanism for
sharing/publishing that public key across repos.
app_refshas noequivalent problem since app bundles aren't per-recipient encrypted.
APPS_TIMEZONE) also need an explicit policy — silently overwrite, orfail loud like the existing app-name-conflict check in
ansible/deploy.yml.Proposed direction (not designed yet)
env_refs(list, mirroringapp_refs) intargets/*.yml.ansible/deploy.yml(or a new step) decrypts each source, unions theapps:lists before renderingAPPS=(or unions the already-renderedAPPS=values), and fails loud on any other key collision across sources— matching the existing app-conflict philosophy instead of introducing
silent overwrite behavior.
keys/*.pubas adiscoverable asset/convention, or require the target repo owner to hand
out the pubkey out-of-band.
Related
Surfaced during final review of #102, same session as #103 (ansible
ref-resolution dedup).