Skip to content
FlightStack Docs
Sign in Start free

Secrets management

FlightStack has three different stores for “things you don’t want printed in logs”:

StoreUse for
VariablesNon-sensitive configuration values.
SecretsSensitive strings — API tokens, webhook URLs, passwords.
Code-signing vaultBinary signing material — keystores, provisioning profiles, certs.

Use the most specific store for each kind. Cross-using (e.g. base64-encoded keystore in a secret) works but loses the per-store benefits — expiration tracking, file-type validation, agent-side decryption with shred-on-exit.

  • Endpoints, feature flags, env names → Variables
  • API tokens, Slack webhook URLs, Sentry DSNs → Secrets
  • Android keystores, iOS .p12 certs and .mobileprovision filesCode-signing vault
  • App Store Connect API keys (.p8) → Code-signing vault
  • Google Play service-account JSON → Code-signing vault
  • Firebase service-account JSON, google-services.json, GoogleService-Info.plist → Code-signing vault

Pick the broadest scope that doesn’t create cross-team leakage:

  • Org scope — shared infrastructure (Sentry, observability tokens, shared signing).
  • Variable groups — shared “envelopes” you attach to multiple pipelines (staging vs prod).
  • Repo scope — repo-specific values.
  • Pipeline scope — pipeline-specific overrides.

The full resolution order is in variables → scope resolution.

Terminal window
# Cycle the org-level API key
curl -X POST https://api.flightstack.voostack.com/organization/$ORG_ID/api-key/rotate \
-H "Authorization: Bearer $TOKEN"

For tokens you generate elsewhere, the loop is:

  1. Generate a new token in the source system (Sentry, Slack, etc).
  2. Update the FlightStack secret with the new value.
  3. Confirm a downstream pipeline runs green.
  4. Revoke the old token in the source system.

For maximum overlap, set the secret to a comma-separated list of oldToken,newToken, swap your client to try each in order, then drop the old one once a few green builds confirm the new one works.

Apple cert / provisioning profile rotation is its own ritual — see Code signing → renewing certificates. Track expiration on each vault entry (expiresAt) so the dashboard nags you a month out.

GET /secrets/variables?includeInactive=true lists every variable with metadata (who created, last updated, last accessed). The dashboard’s Activity log records secret reads at job-execution time — useful when a deploy went sideways and you need to know which pipeline consumed which secret.

  1. No secrets in commit messages or pipeline names. They appear in logs and notifications by default.
  2. Mask early. echo $TOKEN will mask; echo $TOKEN | base64 will mask the base64 too. But echo "$TOKEN reversed: $(echo $TOKEN | rev)" won’t — the reversed value isn’t recognized as the secret. Avoid transforms that defeat masking.
  3. Prefer the vault for blobs. A keystore stuffed into a secret can’t be expired or rotated cleanly; the vault handles both.
  4. Set expiresAt on signing credentials. The dashboard’s expiry banners and the /health endpoint surface them.
  5. Audit on a quarterly cadence. Delete anything no pipeline references.