feat(credentials): mirror backup creds + age key into Vault (CONTRACT_002)
foundation/backup/backup-credentials was never populated in Vault. Add a writer (same ADR-007 docker-exec-over-SSH pattern, GATE A / dependsOn vault.init) that mirrors the config-seeded offsite S3 creds and the age key into Vault, completing CONTRACT_002 §2.3 for in-Vault consumers (Layer-1 ESO, the weekly backup-verify job). - config.ts: loadBackupSecrets() — single reader of the backup secret slice (offsite creds + age recipient/identity), keeping components off raw Config. - credentials.ts: writeBackupCredentialsToVault() — idempotent vault kv put; secret values on stdin (D2), non-secrets as shell vars. - index.ts: wire it beside the data-plane creds writer. Keys written: offsiteEndpoint, offsiteAccessKey, offsiteSecretKey, backupAgeRecipient, backupAgeIdentity. Validated live: +1 resource, then 42 unchanged (idempotent); vault kv get shows all five keys populated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
92e8f978a5
commit
f2ef9bc922
3 changed files with 95 additions and 1 deletions
|
|
@ -6,13 +6,14 @@
|
|||
// fill the marked slots — this file is the single composition point; components stay
|
||||
// pure factories in components/*.
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { loadConfig } from "./config";
|
||||
import { loadConfig, loadBackupSecrets } from "./config";
|
||||
import { buildBaseContext, DeployCtx } from "./lib/context";
|
||||
import { deployNetwork } from "./components/network";
|
||||
import { deployDns } from "./components/dns";
|
||||
import {
|
||||
generateCredentials,
|
||||
writeCredentialsToVault,
|
||||
writeBackupCredentialsToVault,
|
||||
} from "./components/credentials";
|
||||
import { deployPostgres } from "./components/postgres";
|
||||
import { deployRustfs } from "./components/rustfs";
|
||||
|
|
@ -47,6 +48,8 @@ const vault = deployVault(ctx);
|
|||
// --- GATE A: Vault init + unseal (T05). T06 writes the generated data-plane creds
|
||||
// into Vault (CONTRACT_002), dependsOn vault.init so it runs only once unsealed.
|
||||
const vaultCreds = writeCredentialsToVault(ctx, credentials, vault);
|
||||
// Mirror the config-seeded backup creds + age key into Vault (CONTRACT_002 §2.3).
|
||||
const backupCreds = writeBackupCredentialsToVault(ctx, vault, loadBackupSecrets());
|
||||
// =============================================================================
|
||||
// PHASE 6 — FORGE (depends on: credentials, GATE A)
|
||||
// T07 caddy ✓ · T08 forgejo · T10 runner
|
||||
|
|
@ -77,6 +80,7 @@ const runner = cfg.features.runner ? deployRunner(ctx, forgejo) : undefined;
|
|||
// Stack outputs (extended as phases land).
|
||||
// vaultCreds (T06) is a gate for Forgejo (T08) — it has no output to export yet.
|
||||
void vaultCreds;
|
||||
void backupCreds; // CONTRACT_002 backup/backup-credentials mirror; no secret output
|
||||
|
||||
export const phase = "T10-runner"; // forge + CI runner live
|
||||
export const caddyImageId = proxy.imageId;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue