CI/CD Integration

Learn how to use SecretStash in CI/CD pipelines with the Testing environment type and temporary device keys for safe, automated secret access.

SecretStash integrates into your CI/CD pipeline so that your automated builds, tests, and deployments can securely pull the environment variables they need — without risking accidental modifications to your secrets.

The Testing Environment Type

When you create an environment in SecretStash, you assign it a type: local, development, production, or testing. The Testing type is purpose-built for CI/CD pipelines and automated workflows.

Why It Exists

In a typical CI/CD pipeline, scripts and runners have broad access to environment variables. Without guardrails, an automated process could inadvertently push modified or stale values back to your centralized secret store, overwriting carefully managed production or staging secrets. The Testing environment type eliminates this risk by enforcing a strict read-only policy via the CLI.

How It Works

  • Pull is allowed. Your CI/CD runner can use secret-stash:variables pull to retrieve the latest encrypted variables, decrypt them locally, and populate the .env file needed for builds and tests.
  • Push is blocked. Any attempt to use secret-stash:variables push, create, update, or delete variables through the CLI is rejected with an error. The API returns a 403 response, ensuring no write operations succeed.
  • Web-only management. All variable changes for a Testing environment must be made through the SecretStash web application. This keeps secret management centralized with authorized team members who can review changes before they reach your pipeline.

Setting Up SecretStash for CI/CD

Create a Testing environment

In the SecretStash web application, navigate to your application and create a new environment. Set the Type to testing and choose a slug that matches your CI APP_ENV value (e.g., testing or ci).

See Creating an Environment for detailed instructions.

Add your variables

Using the SecretStash web application, add all the environment variables your CI/CD pipeline needs. Since the Testing environment is write-protected via the CLI, these values can only be modified by authorized team members through the web interface.

Generate an API token

Create a dedicated API token for your CI/CD runner. Navigate to your profile settings in SecretStash, open the Tokens tab, and create a new token. Give it a descriptive name like "CI/CD Runner" so you can identify it later.

See API Tokens for more details.

Configure your pipeline

Add the following environment variables to your CI/CD platform's secret store (e.g., GitHub Actions secrets, GitLab CI variables):

SECRET_STASH_API_TOKEN=your_ci_token_here
SECRET_STASH_APPLICATION_ID=your_application_id_here

Install and pull in your pipeline

In your CI/CD workflow, install the SecretStash CLI and pull your variables before running your build or test steps:

# Example: GitHub Actions
- name: Install dependencies
  run: composer install

- name: Pull environment variables
  run: php artisan secret-stash:variables pull --environment=testing

Benefits

  • Prevent accidental overwrites. Automated processes cannot push changes back to SecretStash, protecting your secrets from unintended modifications.
  • Centralized control. Only authorized team members can update CI/CD secrets through the web interface, maintaining a clear audit of who changed what.
  • Consistent builds. Every pipeline run pulls the same set of reviewed, approved variables — no drift from local developer changes.
  • Zero-knowledge security. Even in CI/CD, variables are decrypted locally by the CLI. SecretStash servers never see your plaintext secrets.

Temporary Device Keys

For CI/CD pipelines that need to authenticate as a device without persisting long-lived key material, SecretStash supports temporary device keys. These are short-lived RSA key pairs that are automatically registered with the server and expire after a configurable time-to-live (TTL).

Why Use Temporary Keys?

Standard device keys live in ~/.secret-stash/ and persist indefinitely. In ephemeral CI/CD environments — where runners are created and destroyed per job — you may not want to pre-provision permanent device keys or manage their lifecycle across disposable machines. Temporary keys solve this by:

  • Generating an isolated key pair in a random /tmp directory per pipeline run.
  • Automatically expiring on the server after the TTL, so no manual cleanup of registered devices is required.
  • Skipping all interactive prompts, making them suitable for headless/non-interactive CI environments.

Workflow

Initialize a temporary key

Run the secret-stash:keys init command with the --temporary flag. This generates an RSA-4096 key pair into an isolated temp directory and registers it with the SecretStash server:

php artisan secret-stash:keys init --temporary --ttl=15

The --ttl flag sets how long the key is valid, in minutes (minimum 5, maximum 60, default 15). Choose a TTL that comfortably covers your pipeline duration.

You can optionally provide a custom label with --label:

php artisan secret-stash:keys init --temporary --ttl=30 --label="GitHub Actions - Build #123"

If --label is omitted, the default label is CI/CD Temporary Key (<hostname>).

Export the key directory

The init --temporary command outputs the path to the temporary key directory. Export it so that subsequent CLI commands can find the keys:

export SECRET_STASH_KEY_DIR=/tmp/secret-stash-tmp-<random-hex>

Once SECRET_STASH_KEY_DIR is set, all SecretStash CLI commands will read device keys from that directory instead of the default ~/.secret-stash/. See Key Directory Override for more details.

Use SecretStash commands as normal

With the environment variable set, run any SecretStash command — it will use the temporary key:

php artisan secret-stash:variables pull --environment=testing

Clean up (optional)

After your pipeline completes, delete the temporary key directory for security:

rm -rf "$SECRET_STASH_KEY_DIR"

Full Example: GitHub Actions

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: composer install

      - name: Initialize temporary device key
        run: |
          OUTPUT=$(php artisan secret-stash:keys init --temporary --ttl=15 2>&1)
          echo "$OUTPUT"
          KEY_DIR=$(echo "$OUTPUT" | grep -oP 'SECRET_STASH_KEY_DIR=\K.*')
          echo "SECRET_STASH_KEY_DIR=$KEY_DIR" >> $GITHUB_ENV

      - name: Pull environment variables
        run: php artisan secret-stash:variables pull --environment=testing

      - name: Run tests
        run: php artisan test

      - name: Clean up temporary keys
        if: always()
        run: rm -rf "$SECRET_STASH_KEY_DIR"

Important Notes

  • Server-side expiration. The temporary key expires on the SecretStash server after the configured TTL. Once expired, any CLI command using that key will fail with an API error. There is no client-side expiration check.
  • Device metadata. The device.json metadata file for temporary keys includes is_temporary: true and expires_at fields that are not present in regular device metadata.
  • No interactive prompts. The --temporary flag skips the interactive device label prompt, making it safe for non-interactive and headless environments.
  • Companion backend support. A companion server-side update adds the temporary key model, expiration filtering, and an hourly prune job that automatically removes expired temporary keys from the server.

Next Steps