Cashu ecash mint for BTC and UNIT Runes, deployed through GCP Confidential Space.
The security target is simple: mint secrets and app-level Cloud KMS decrypt capability are available only to the pinned, attested container image. The VM service account should not directly read the Secret Manager payload or decrypt app key material.
- Fastify/TypeScript Cashu mint.
- BTC on-chain ecash as
onchain/sat. - UNIT Runes ecash as
onchain/unit. - Optional Lightning as
bolt11/satthrough LNbits. - Private Cloud SQL for mint state.
- Secret Manager plus app-level Cloud KMS for runtime secrets and keyset encryption.
- Caddy TLS termination inside Confidential Space, with ACME storage persisted through an attestation-gated Secret Manager secret.
main pushes always run CI.
Deploy-relevant main pushes also run
.github/workflows/gcp-confidential-space-release.yml. Relevant paths include
src/**, migrations/**, terraform/gcp/**, gcp-confidential-space/**,
package files, and the release workflow itself.
When release preflight is configured, the workflow:
- Builds the Confidential Space workload image.
- Attests the image digest.
- Applies Terraform with the pinned digest.
- Restarts the Confidential Space VM.
- Health-checks the mint.
- Generates and signs the deployment security attestation.
- Uploads the attestation JSON, markdown summary, and checksum.
If required GitHub environment variables or secrets are missing, preflight skips deployment without touching GCP.
.github/workflows/gcp-confidential-space-audit-monitor.yml also runs on a
schedule. It reruns the live verifier and fails when recent sensitive admin
activity comes from a principal other than the configured deploy service
account.
To find the evidence that CI did not reveal KMS keys or read secrets:
- Open GitHub Actions for this repo.
- Open the successful GCP Confidential Space Release run for the deployed commit.
- Open the run summary and artifact list.
- Download artifact
gcp-confidential-space-deployment-attestation. - Inspect:
gcp-confidential-space-deployment-attestation.mdgcp-confidential-space-deployment-attestation.jsongcp-confidential-space-deployment-attestation.json.sha256
The markdown summary has a Key Handling Claims section. The JSON has the
same evidence under claims. The important claims are:
{
"verifierDidNotReadSecretPayloads": true,
"verifierDidNotRequestKmsDecrypt": true,
"verifierDidNotRequestKmsEncrypt": true,
"kmsKeyMaterialWasNotExportedToCi": true,
"appKmsAccessIsBoundToAttestedImageDigest": true,
"secretManagerAccessIsBoundToAttestedImageDigest": true,
"runtimeServiceAccountHasNoDirectAppKmsAccess": true,
"runtimeServiceAccountHasNoDirectSecretAccess": true,
"caddyAcmeStorageIsPersisted": true
}Also check:
resultispass;subject.imageDigestmatches the deployed image digest;- the SHA-256 file matches the downloaded JSON;
- the workflow step Attest deployment security predicate completed successfully.
Private release evidence should keep the full attestation artifact, checksum, audit review notes, and operator review record. Do not commit secret payloads, database URLs, admin bearer tokens, service account keys, or raw audit exports.
npm install
cp .env.example .env
docker-compose up -d
npm run migrate
npm run devUseful checks:
npm run lint
npm run build
npm testManual diagnostics live in scripts/dev/. They are not part of CI, deploy, or
release evidence.
src/ mint application
migrations/ SQL migrations used by npm run migrate
gcp-confidential-space/ Confidential Space container files
terraform/gcp/ GCP infrastructure
scripts/interop/ wallet compatibility flows
scripts/dev/ manual diagnostics and one-off helpers
docs/ detailed security and deployment notes
tests/ unit and integration tests
docs/security.mddocs/gcp-confidential-deployment.mddocs/release-evidence.mddocs/private-operations.mddocs/archive/for historical notes only