DevSecOps

Travis CI Security Best Practices

Security hardening for Travis CI pipelines covering secret management, build isolation, and migration considerations for teams still on the platform.

Bob
Senior Security Consultant
6 min read

Travis CI occupies an awkward spot in 2023. It was the dominant CI platform for open-source projects throughout the 2010s, but a series of security incidents and business changes have eroded trust. The 2021 exposure of environment variables from public repositories — affecting tens of thousands of projects — demonstrated systemic issues with how Travis handled secrets.

If your organization still uses Travis CI, you need a hardened configuration today and a migration plan for tomorrow. This guide covers both.

The Security Track Record

In September 2021, researchers discovered that Travis CI exposed secure environment variables from public repository builds to anyone who could view build logs. This was not a subtle vulnerability — it was a fundamental flaw in how the platform isolated secrets between forks and pull requests.

Earlier incidents included insecure default behavior around fork pull requests, where secrets were available to PR builds from forks. Travis eventually changed this default, but the damage was done — projects that had been running for years had potentially exposed credentials.

Understanding this history is important because it informs how aggressively you need to restrict your Travis configuration.

Encrypt Everything

Travis supports encrypted environment variables and encrypted files. Use both.

env:
  global:
    - secure: "encrypted-base64-string..."

Generate encrypted values using the Travis CLI:

travis encrypt DEPLOY_KEY=supersecret --add env.global

Never put plaintext secrets in .travis.yml. This seems obvious, but repository archaeology regularly turns up commits where developers added credentials "temporarily" and forgot to remove them.

For files (like GCP service account keys), use Travis's file encryption:

travis encrypt-file service-account.json --add

This adds the encrypted file to your repo and the decryption step to your build configuration.

Restrict Fork and Pull Request Builds

The single most important security setting in Travis CI:

# In Travis CI web settings, NOT in .travis.yml:
# - Build pushed pull requests: ON
# - Build pushed branches: ON  
# - Build fork pull requests: OFF (or carefully restricted)

When "Build fork pull requests" is enabled, external contributors' PRs are built on your Travis infrastructure. If secrets are available to PR builds (the old default), fork PRs can exfiltrate them.

Even with the newer default that restricts secrets from fork PRs, the builds still consume your CI minutes and can run arbitrary code on Travis's shared infrastructure. Turn fork PR builds off unless you have a specific need.

If you must build fork PRs:

  • Verify that secrets are NOT available to fork PR builds.
  • Use a separate, restricted configuration for PR builds versus branch builds.
  • Review fork PR build logs for suspicious activity.

Build Isolation

Travis runs builds in VMs or containers. The isolation depends on your plan and configuration:

# Use VM-based builds for better isolation
os: linux
dist: focal
sudo: required

Container-based builds share kernel resources. VM-based builds provide stronger isolation. For security-sensitive workflows, always use VM-based builds.

Conditional Deployment

Gate deployments on branch and build conditions:

deploy:
  provider: script
  script: bash scripts/deploy.sh
  on:
    branch: main
    condition: $TRAVIS_PULL_REQUEST = false
    tags: true

The condition: $TRAVIS_PULL_REQUEST = false ensures deployments only happen on direct branch pushes, not PR builds. Adding tags: true restricts deployment to tagged releases.

Limit Build Script Complexity

Travis's build lifecycle (before_install, install, before_script, script, after_success, deploy) makes it tempting to put logic everywhere. Resist this.

  • Keep .travis.yml minimal. It should define the environment and call scripts.
  • Store build logic in shell scripts in the repository.
  • Review changes to .travis.yml and build scripts with the same rigor as application code.
# Prefer
script:
  - bash scripts/test.sh
  - bash scripts/security-scan.sh

# Over
script:
  - |
    if [ "$TRAVIS_BRANCH" = "main" ]; then
      npm run build
      npm run test
      # 30 more lines...
    fi

Add Security Scanning

Travis does not provide built-in security scanners like GitLab does. You need to add them yourself:

script:
  - npm audit --production --audit-level=high
  - npx semgrep --config auto --error .
  - docker run --rm -v $(pwd):/src aquasec/trivy fs /src

after_script:
  - bash scripts/upload-scan-results.sh

Run scanners as part of the main script phase so failures break the build. Upload results to a centralized platform for tracking.

Notification Security

Travis can send build notifications to Slack, email, and webhooks. Secure these channels:

  • Use encrypted webhook URLs.
  • Do not include build environment details in notifications that go to public channels.
  • Monitor notification channels for signs of compromise (unexpected messages, altered content).

Cache Security

Travis caches can persist between builds. A compromised build can poison the cache:

cache:
  directories:
    - node_modules
  timeout: 300
  • Periodically clear caches (Travis supports manual cache clearing via the API).
  • Use cache keys tied to lockfile hashes when possible.
  • Do not cache sensitive data like credentials or tokens.

Migration Planning

Given Travis CI's security history and uncertain future, every team still on the platform should have a migration plan:

  1. Audit current usage: What secrets are stored in Travis? What does each pipeline do?
  2. Evaluate alternatives: GitHub Actions (if you are on GitHub), GitLab CI, CircleCI, or self-hosted options.
  3. Migrate secrets first: Move credentials to your target platform or a secrets manager. Rotate any credential that was ever stored in Travis.
  4. Migrate pipelines: Start with the simplest pipelines. Validate equivalence by running both platforms in parallel.
  5. Decommission: Remove Travis configuration, revoke Travis's access to your repositories, and rotate any remaining shared credentials.

Monitoring During Transition

While you are still on Travis, actively monitor:

  • Build logs for unexpected content or exfiltration attempts.
  • API access patterns for your Travis organization.
  • Any Travis security advisories.
  • Changes to .travis.yml across all repositories.

How Safeguard.sh Helps

Safeguard.sh provides visibility into your CI/CD security posture across all platforms — including legacy systems like Travis CI that you may be migrating away from. It inventories every secret reference, scans pipeline configurations for insecure patterns, and tracks your migration progress. When you are running pipelines across multiple CI/CD platforms during a transition, Safeguard.sh gives you a single view of security coverage, policy compliance, and vulnerability status regardless of where your builds actually run.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.