Problem
vaults/*.yml can currently only source values from the current repo's
own secrets/vars GitHub context (GITHUB_SECRETS_JSON/GITHUB_VARS_JSON
in encrypt-env). There's no way for a vault to pull in a value that's
only known to a different repository — e.g. a third repo holds a
Telegram bot token as its own secret, and several other repos' vaults need
to include that value without each of them independently knowing the raw
secret.
If the source repo is in the same GitHub organization, this is already
solved natively by GitHub Organization Secrets (shared across repos by
policy) — no new flightdeck mechanism needed for that case. This issue is
specifically for when that's not enough: a different org, or a value
that's produced by another repo's own vault-preparation pipeline rather
than being a static GH secret.
Proposal
Let a vault manifest declare other already-published, encrypted vault
assets to import:
asset: hawkeye.sops.envkeys:
- hawkeyevaults:
- owner/repo3@latest:shared.sops.envenv:
APPS_DOMAIN: RUBYKATZEN_COM_DOMAINTELEGRAM_BOT_TOKEN: TELEGRAM_BOT_TOKEN # sourced from the imported vault
At encrypt time, before rendering env:, encrypt-env would download each
vaults: entry's asset, decrypt it, parse it as dotenv, and add its
key=value pairs into the pool of sources available to render_env()'s
resolution — alongside (not replacing) GITHUB_SECRETS_JSON/
GITHUB_VARS_JSON.
Mechanics / open questions to resolve when designing this
- A new CI-side decrypt key is required. No private age key material
exists in CI today — the server's own private key
(flightdeck_sops_age_key_file) only ever lives on the target server,
never in CI. Importing a vault means decrypting it during the CI build
step, which needs its own dedicated keypair: the source vault
(owner/repo3) encrypts for this recipient specifically, and the
private half lives as a CI secret in whichever repo(s) perform the
import (a new encrypt-env input, e.g. import-age-key). This is a
genuinely new trust boundary, distinct from the existing keys: (who
the output vault is encrypted for) — worth being deliberate about, not
bolted on casually. - Resolution precedence. Today it's secrets > variables. Adding
imported-vault values as a third source needs an explicit rule: does an
imported value win over this repo's own secret of the same source name,
or lose? Or is a name collision here an error, matching the fail-loud
philosophy already used for env_refs merging in ansible/deploy.yml? - Cycle protection. If vaults can import each other by ref, a
self-reference or cycle (A imports B, B imports A) needs at least a
documented "don't do this." Doesn't need hard validation given the
"keep readers dumb" philosophy used elsewhere in this repo
(load-yaml-matrix), but worth deciding consciously rather than
discovering it by accident. - Scope of what gets imported. Import brings in all of the source
vault's decrypted key=value pairs, not a scoped subset — worth
confirming that's actually wanted vs. letting the importing manifest
cherry-pick specific keys.
Related
#104 (env_refs / multi-vault merging) explicitly flagged cross-repo
age-key distribution as an unresolved obstacle — this issue is the
concrete proposal for solving it. Touches .github/actions/encrypt-env
(render-env.py, action.yml) and the vault manifest schema documented
in the main README's "Vaults And Targets" section.
Not urgent — deliberately deferred, real design work needed before
implementing.
Problem
vaults/*.ymlcan currently only source values from the current repo'sown
secrets/varsGitHub context (GITHUB_SECRETS_JSON/GITHUB_VARS_JSONin
encrypt-env). There's no way for a vault to pull in a value that'sonly known to a different repository — e.g. a third repo holds a
Telegram bot token as its own secret, and several other repos' vaults need
to include that value without each of them independently knowing the raw
secret.
If the source repo is in the same GitHub organization, this is already
solved natively by GitHub Organization Secrets (shared across repos by
policy) — no new flightdeck mechanism needed for that case. This issue is
specifically for when that's not enough: a different org, or a value
that's produced by another repo's own vault-preparation pipeline rather
than being a static GH secret.
Proposal
Let a vault manifest declare other already-published, encrypted vault
assets to import:
At encrypt time, before rendering
env:,encrypt-envwould download eachvaults:entry's asset, decrypt it, parse it as dotenv, and add itskey=value pairs into the pool of sources available to
render_env()'sresolution — alongside (not replacing)
GITHUB_SECRETS_JSON/GITHUB_VARS_JSON.Mechanics / open questions to resolve when designing this
exists in CI today — the server's own private key
(
flightdeck_sops_age_key_file) only ever lives on the target server,never in CI. Importing a vault means decrypting it during the CI build
step, which needs its own dedicated keypair: the source vault
(
owner/repo3) encrypts for this recipient specifically, and theprivate half lives as a CI secret in whichever repo(s) perform the
import (a new
encrypt-envinput, e.g.import-age-key). This is agenuinely new trust boundary, distinct from the existing
keys:(whothe output vault is encrypted for) — worth being deliberate about, not
bolted on casually.
imported-vault values as a third source needs an explicit rule: does an
imported value win over this repo's own secret of the same source name,
or lose? Or is a name collision here an error, matching the fail-loud
philosophy already used for
env_refsmerging inansible/deploy.yml?self-reference or cycle (A imports B, B imports A) needs at least a
documented "don't do this." Doesn't need hard validation given the
"keep readers dumb" philosophy used elsewhere in this repo
(
load-yaml-matrix), but worth deciding consciously rather thandiscovering it by accident.
vault's decrypted key=value pairs, not a scoped subset — worth
confirming that's actually wanted vs. letting the importing manifest
cherry-pick specific keys.
Related
#104 (
env_refs/ multi-vault merging) explicitly flagged cross-repoage-key distribution as an unresolved obstacle — this issue is the
concrete proposal for solving it. Touches
.github/actions/encrypt-env(
render-env.py,action.yml) and the vault manifest schema documentedin the main README's "Vaults And Targets" section.
Not urgent — deliberately deferred, real design work needed before
implementing.