Skip to content

Latest commit

 

History

History
122 lines (82 loc) · 3.84 KB

File metadata and controls

122 lines (82 loc) · 3.84 KB

Test Fixture Management

Integration test fixtures contain encrypted FHE data (secret keys, ciphertext blobs) and are stored as a GPG-encrypted archive (tests/fixtures.tar.gz.gpg) to prevent plaintext secrets from being committed to the repository.

How It Works

CI decrypts fixtures at test time using a passphrase stored in GitHub Secrets. Two secret slots are used in alternation to allow atomic updates without breaking other PRs:

Secret Description
FIXTURES_GPG_PASSPHRASE Slot A
FIXTURES_GPG_PASSPHRASE_ALT Slot B

The CI workflow (ci.yml) always references one of these by name. A fixture update PR swaps the reference to the other slot, so the old passphrase remains valid for any in-flight PRs until they rebase.

Updating Fixtures

Prerequisites

  • enVector Cloud access (ENVECTOR_ENDPOINT, ENVECTOR_API_KEY)
  • GitHub repo admin access (to update Secrets)
  • mise run setup completed

Step-by-step

1. Check which secret slot CI currently uses

Open .github/workflows/ci.yml and find the FIXTURES_GPG_PASSPHRASE line:

# If this says FIXTURES_GPG_PASSPHRASE, the next slot is FIXTURES_GPG_PASSPHRASE_ALT
# If this says FIXTURES_GPG_PASSPHRASE_ALT, the next slot is FIXTURES_GPG_PASSPHRASE
FIXTURES_GPG_PASSPHRASE: ${{ secrets.FIXTURES_GPG_PASSPHRASE }}

2. Generate a new random passphrase

openssl rand -base64 32

Copy the output — you will need it for steps 3 and 4.

3. Store the passphrase in the OTHER secret slot

If CI currently uses FIXTURES_GPG_PASSPHRASE, set the new passphrase in FIXTURES_GPG_PASSPHRASE_ALT, and vice versa.

# Example: setting the ALT slot
gh secret set FIXTURES_GPG_PASSPHRASE_ALT
# Paste the passphrase from step 2, then press Enter and Ctrl+D

4. Generate new fixtures

ENVECTOR_ENDPOINT=... ENVECTOR_API_KEY=... python scripts/generate-test-fixtures.py

This connects to enVector Cloud and writes plaintext fixtures to tests/fixtures/.

5. Encrypt fixtures with the new passphrase

FIXTURES_GPG_PASSPHRASE="<passphrase from step 2>" mise run fixtures:encrypt

This creates tests/fixtures.tar.gz.gpg. Verify the file was updated:

git diff --stat  # should show tests/fixtures.tar.gz.gpg changed

6. Update CI to reference the new secret slot

Edit .github/workflows/ci.yml — swap the secret name:

# Before (example)
FIXTURES_GPG_PASSPHRASE: ${{ secrets.FIXTURES_GPG_PASSPHRASE }}

# After
FIXTURES_GPG_PASSPHRASE: ${{ secrets.FIXTURES_GPG_PASSPHRASE_ALT }}

The environment variable name (FIXTURES_GPG_PASSPHRASE) stays the same — only the secret reference changes.

7. Clean up and commit

rm -rf tests/fixtures/          # Remove plaintext fixtures
git add tests/fixtures.tar.gz.gpg .github/workflows/ci.yml
git commit -m "chore: update test fixtures and rotate GPG passphrase"

8. Submit PR and verify

Push the branch and confirm CI passes with the new secret slot. After merge, the old slot becomes stale and will be overwritten on the next rotation.

Decrypting Fixtures Locally

To run integration tests locally, you need the current passphrase:

export FIXTURES_GPG_PASSPHRASE="<current passphrase>"
mise run fixtures:decrypt
mise run test

Fixture Contents

Generated by scripts/generate-test-fixtures.py:

File Description
keys/SecKey.json FHE secret key (for decryption in tests)
keys/EncKey.json FHE encryption key
ciphertext_score.b64 Base64-encoded CiphertextScore protobuf blob
expected_scores.json Expected decrypted scores (test assertions)
metadata_envelopes.json AES-encrypted metadata envelopes
expected_metadata.json Expected plaintext metadata (test assertions)
config.json Test parameters (team_secret, agent_id, dim, etc.)