spade secret

The spade secret command manages secrets — database connection strings, API keys, and other sensitive values — used by pipeline blocks. By default it manages local secrets: values are stored in the operating-system keychain and injected into blocks at run time by spade run, so they never appear in a pipeline file, logs, or on disk. With --remote it manages your cloud secrets instead, the ones cloud runs resolve.

A pipeline block references a secret by name in its secrets mapping. The block author reads it with get_secret("<logical-name>"); the pipeline binds that logical name to one of your stored secrets:

- id: 019cf4bc-2222-7000-0000-000000000000
  name: db.query
  args:
    query: "SELECT * FROM parcels"
  secrets:
    db: prod-postgres-dsn   # value is the NAME of a stored secret, never the secret

Usage🔗

spade secret set <name>     # store a value (prompted, or piped via stdin)
spade secret list           # list stored secret names
spade secret rm <name>      # remove a secret

spade secret set --remote <name>   # the same three, against the cloud store
spade secret list --remote
spade secret rm --remote <name>

Setting a secret🔗

The value is read from the terminal without echoing:

spade secret set prod-postgres-dsn
Enter secret value: ················
Stored secret "prod-postgres-dsn" in the OS keychain.

Or piped from standard input, for scripting:

echo "$DATABASE_URL" | spade secret set prod-postgres-dsn

Storage🔗

Secrets are kept in the OS keychain:

PlatformBackend
macOSKeychain
WindowsCredential Manager
LinuxSecret Service (libsecret)

spade secret list cannot ask the OS keychain to enumerate its entries, so the CLI separately maintains a small index of secret names (never values) under a reserved keychain key to back the list command.

Errors🔗

If a pipeline block references a secret that is not in the keychain, spade run fails with an actionable message naming the secret and how to set it:

resolving secrets for block db.query: secret "prod-postgres-dsn" (bound to "db")
is not in the local keychain; set it with `spade secret set prod-postgres-dsn`

Cloud secrets🔗

--remote on any of the three commands targets the cloud secret store instead of the keychain: the key-management service that cloud pipeline runs resolve secrets from. It reaches the cloud through the web UI's secrets proxy with your spade login session, so it needs one. The web UI's Secrets page manages the same store.

spade secret set --remote prod-postgres-dsn
Enter secret value: ················
Stored cloud secret "prod-postgres-dsn".

Local and cloud secrets are independent namespaces. The same logical name in a pipeline's secrets mapping resolves to the keychain value under spade run and to the cloud value under spade submit, so a pipeline can use a development credential locally and a production one in the cloud without being edited.

Values are write-only in the cloud: list --remote returns names, and nothing ever displays a stored value.

Two things depend on cloud secrets: the secrets mapping in a pipeline block, and the clone secret a private collection is published with — a read-only repository token the registry uses to clone a private repository, named with spade publish --clone-secret.

Secret names use letters, digits, ., _, and -, and start with a letter or digit.