Skip to content
chalupa
How it worksSecurityDocumentation
Open console
Menu
How it worksSecurityDocumentationOpen console
chalupa

Operational signal for ephemeral environments. Compute can be torn down while persistent data follows its own lifecycle.

Product

How it worksSecurityConsole

Learn

QuickstartConceptsAPI and schema

Built for ephemeral operations, not forgotten resources.

All displayed costs are estimates.

Documentation/Secrets with tvault
/

Start here

QuickstartSecrets with tvault

Operating model

Conceptschalupa.yml referenceLifecycleTunnels and securityData and seeds

Control plane

Control plane and agentSuites and artifactsCosts and idle observation

Reference

Private operationsTroubleshootingAPI and schema
Browse documentation
/

Start here

QuickstartSecrets with tvault

Operating model

Conceptschalupa.yml referenceLifecycleTunnels and securityData and seeds

Control plane

Control plane and agentSuites and artifactsCosts and idle observation

Reference

Private operationsTroubleshootingAPI and schema

Start here

Secrets with tvault

Inject only the credentials each process needs, without copying them into the repository, temporary files, or logs.

Reviewed 2026-07-23

Chalupa separates configuration from secrets. chalupa.yml, .env.example, and the runbooks describe names and contracts; tvault stores encrypted values. A process receives a secret only while running the command that needs it.

Secret map

Key Consumer Scope
DIGITALOCEAN_API_TOKEN Local Pulumi tasks Operator-requested provisioning and destruction. It never reaches the droplet or control plane.
CHALUPA_INGEST_KEY Agent, task report, and Chalupa Signs heartbeats, events, and suite runs.
DATABASE_URL Chalupa Pooled Neon/Postgres connection.
CLOUD_ADMIN_TOKEN Chalupa Creates the private administrator session.
CRON_SECRET Scheduler and Chalupa Authorizes reconciliation and retention jobs.
DIGITALOCEAN_READ_TOKEN Cost reconciliation Read-only inventory access. It cannot create or destroy resources.

The current release uses one fleet-wide ingestion key. Treat it as a shared credential: rotating it requires updating the control plane and recreating or reconfiguring every agent.

Diagnose without reading values

Secret names are metadata. Verify availability without unlocking or printing values:

tvault doctor --project chalupa --json
tvault list --project chalupa --json --names-only

tvault status --json also reports whether the vault and local agent are available. None of these commands returns secret values.

Create generated credentials

Send random credentials directly to tvault over stdin. Redirecting the command result keeps operational output separate from secret-management output:

openssl rand -hex 32 |
  tvault set --project chalupa CLOUD_ADMIN_TOKEN --stdin >/dev/null

openssl rand -hex 32 |
  tvault set --project chalupa CHALUPA_INGEST_KEY --stdin >/dev/null

openssl rand -hex 32 |
  tvault set --project chalupa CRON_SECRET --stdin >/dev/null

DATABASE_URL and DIGITALOCEAN_READ_TOKEN come from their providers. Send them through stdin or import them from a controlled file. Do not place them in command arguments when your shell records history.

Run with least privilege

Repository tasks already pass through fixed profiles in src/cli/with-tvault.ts:

Workflow Profile boundary
task data-up, task up, task down, task data-nuke Provisioning token, plus the ingest key only when Chalupa reporting needs it.
task report Ingest key only.
task cloud:db:migrate Database URL only.
task cloud:staging-check The five control-plane runtime credentials, never the provisioning token.

Do not invoke the internal underscore-prefixed lifecycle tasks directly; the public tasks establish the credential boundary.

For backward compatibility, only the provisioning profile can read DIGITALOCEAN_API_TOKEN from ~/.config/secrets/env after tvault is missing or cannot return that key. The parser treats the file as data and never evaluates shell syntax. Database, admin, ingest, cron, and read-only provider credentials never use this fallback. Move the provisioning key into tvault and treat the file as a temporary migration path.

Prefer tvault run --only to exporting an entire project. Values exist only in the subprocess environment:

tvault run \
  --project chalupa \
  --only DATABASE_URL,CLOUD_ADMIN_TOKEN,CHALUPA_INGEST_KEY,CRON_SECRET,DIGITALOCEAN_READ_TOKEN \
  -- bun run dev

Run that command from cloud/. For a local tour without a database, set CHALUPA_DATA_MODE=demo and inject only CLOUD_ADMIN_TOKEN.

Do not use eval $(tvault env) as the normal workflow. It expands both the lifetime and scope of credentials in your shell. Do not persist tvault env output in .env.local.

tvault:// templates

When a command needs to rename a key, a committed template may contain a reference, never the value:

DIGITALOCEAN_TOKEN=${tvault://chalupa/DIGITALOCEAN_API_TOKEN}

tvault run --env-file <template> -- <command> resolves the reference at runtime. Its dotenv parser does not evaluate shell substitutions or commands.

Deliver secrets to the platform

A deployment receives the same keys through the platform's encrypted secret store. tvault can remain the local source of truth, but the platform keeps its own encrypted copy. Use a stdin-based workflow and confirm key names, not values.

After configuring staging:

  1. confirm that all five control-plane runtime credentials are present;
  2. run the database migration before accepting traffic;
  3. check readiness without returning configuration details;
  4. sign and submit one synthetic ingestion request;
  5. record who performed the synchronization and when.

Never reuse DIGITALOCEAN_API_TOKEN as the control plane's read-only token. The control plane must receive the narrowest provider scope available.

Rotation and revocation

Rotate one credential at a time and keep a recovery path:

  1. create the new version in tvault;
  2. update the remote consumer;
  3. verify readiness and the affected workflow;
  4. restart or replace agents when the HMAC key changes;
  5. revoke the previous value at the provider;
  6. inspect metadata with tvault history --project chalupa <KEY>.

Rotating CLOUD_ADMIN_TOKEN invalidates existing sessions. Rotating CRON_SECRET requires updating the scheduler. Rotating the read-only token must not affect the local provisioning token.

Rules for agents

  • Use tvault list --names-only for discovery; do not loop over get.
  • Inject values into a trusted subprocess with an explicit allowlist.
  • Never surface stdout from a command that might echo its environment.
  • Do not write secrets to /tmp, artifacts, screenshots, or messages.
  • Do not unlock and relock the vault around every operation.
  • Stop when creating, rotating, or synchronizing a value needs new authority.
PreviousQuickstartNextConcepts

On this page

Secret mapDiagnose without reading valuesCreate generated credentialsRun with least privilegetvault:// templatesDeliver secrets to the platformRotation and revocationRules for agents