Using SSH keys in Bitbucket Pipelines

Overview

Bitbucket Pipelines supports SSH key integration to enable secure authentication and access to external resources within your pipeline workflows.

BITBUCKET_SSH_KEY_FILE Variable

The BITBUCKET_SSH_KEY_FILE default variable provides the location of your private SSH key file within the pipeline environment.

Description: The location of the Bitbucket Pipelines private SSH key.

Key Features

  • File Location: Points to where the private SSH key is stored in the build container

  • Platform Support: Available for pipelines running on Bitbucket Cloud and the Linux Docker Pipelines runner

  • Docker BuildKit: The key can be used with BuildKit to access external resources using SSH

Setting Up SSH Keys

Step 1: Generate SSH Key Pair

Generate a new SSH key pair for your pipeline:

ssh-keygen -t rsa -b 4096 -C "pipelines@company.com" -f pipelines_key -N ""

This creates:

  • pipelines_key (private key)

  • pipelines_key.pub (public key)

Step 2: Add Public Key to Target Server

Copy the public key to the server you want to access:

ssh-copy-id -i pipelines_key.pub user@server.example.com

Or manually add it to ~/.ssh/authorized_keys on the target server.

Step 3: Configure Private Key in Bitbucket

  1. Navigate to Repository settings, then Pipelines, and then select SSH keys.

  2. Paste the private key content.

  3. Save the configuration.

Using SSH Keys in Pipelines

Basic SSH Connection

pipelines: default: - step: script: - ssh user@server.example.com 'bash -s' < deploy.sh

Clone Private Repository

pipelines: default: - step: script: - git clone git@github.com:mycompany/private-repo.git

SCP File Transfer

pipelines: default: - step: script: - npm run build - scp -r dist/ user@server.example.com:/var/www/html/

Rsync Deployment

pipelines: default: - step: name: Deploy with Rsync script: - npm run build - rsync -avz --delete dist/ user@server.example.com:/var/www/html/

SSH Configuration

Custom SSH Config

Create an SSH config file for advanced configurations:

pipelines: default: - step: script: - mkdir -p ~/.ssh - | cat > ~/.ssh/config <<EOF Host production HostName prod.example.com User deploy Port 2222 StrictHostKeyChecking no EOF - chmod 600 ~/.ssh/config - ssh production 'bash deploy.sh'

Multiple SSH Keys

For accessing multiple servers with different keys:

pipelines: default: - step: script: - mkdir -p ~/.ssh - echo "$GITHUB_KEY" > ~/.ssh/github_key - echo "$DEPLOY_KEY" > ~/.ssh/deploy_key - chmod 600 ~/.ssh/*_key - | cat > ~/.ssh/config <<EOF Host github.com IdentityFile ~/.ssh/github_key Host deploy-server HostName deploy.example.com IdentityFile ~/.ssh/deploy_key EOF - git clone git@github.com:mycompany/repo.git - ssh deploy-server 'bash deploy.sh'

Known Hosts

Add Known Host

Prevent SSH host verification prompts:

pipelines: default: - step: script: - ssh-keyscan -t rsa server.example.com >> ~/.ssh/known_hosts - ssh user@server.example.com 'whoami'

Add Multiple Known Hosts

pipelines: default: - step: script: - mkdir -p ~/.ssh - ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts - ssh-keyscan -t rsa gitlab.com >> ~/.ssh/known_hosts - ssh-keyscan -t rsa deploy.example.com >> ~/.ssh/known_hosts - git clone git@github.com:mycompany/repo.git

Skip Host Key Checking (Not Recommended)

pipelines: default: - step: script: - ssh -o StrictHostKeyChecking=no user@server.example.com 'whoami'

Security Risk

Disabling host key checking makes you vulnerable to man-in-the-middle attacks. Only use in trusted networks.

Docker BuildKit with SSH

Use SSH keys with Docker BuildKit for private repository access during builds:

options: docker: true pipelines: default: - step: script: - export DOCKER_BUILDKIT=1 - docker build --ssh default=$BITBUCKET_SSH_KEY_FILE -t myapp:latest .

Dockerfile:

# syntax=docker/dockerfile:1 FROM node:18 # Mount SSH key during npm install RUN --mount=type=ssh \ git clone git@github.com:mycompany/private-lib.git /tmp/private-lib && \ cd /tmp/private-lib && \ npm install && \ npm link WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["npm", "start"]

Common Use Cases

Deploy to Remote Server

pipelines: branches: main: - step: name: Deploy to Production deployment: production script: - npm run build - tar -czf deploy.tar.gz dist/ - scp deploy.tar.gz deploy@prod.example.com:/tmp/ - ssh deploy@prod.example.com 'cd /var/www && tar -xzf /tmp/deploy.tar.gz'

Access Private Git Repositories

pipelines: default: - step: script: - git clone git@github.com:mycompany/private-shared-lib.git - cd private-shared-lib && npm install && npm link - cd .. && npm link shared-lib - npm install - npm test

Database Tunnel

pipelines: default: - step: script: - ssh -f -N -L 5432:localhost:5432 user@db-bastion.example.com - sleep 5 - psql -h localhost -U dbuser -d mydb -c "SELECT version();"

Execute Remote Commands

pipelines: default: - step: name: Restart Services script: - ssh deploy@prod.example.com 'sudo systemctl restart nginx' - ssh deploy@prod.example.com 'sudo systemctl restart app'

SSH Agent

For complex SSH scenarios, use ssh-agent:

pipelines: default: - step: script: - eval $(ssh-agent -s) - echo "$SSH_PRIVATE_KEY" | ssh-add - - ssh-add -l - git clone git@github.com:mycompany/repo.git

Troubleshooting

Permission Denied (publickey)

Cause: SSH key not properly configured

Solution:

  1. Verify public key is on target server

  2. Check private key is in Bitbucket settings

  3. Ensure key permissions are correct (600)

- step: script: - chmod 600 ~/.ssh/id_rsa - ssh user@server.example.com 'whoami'

Host Key Verification Failed

Cause: Target server not in known_hosts

Solution: Add server to known_hosts

- step: script: - ssh-keyscan -t rsa server.example.com >> ~/.ssh/known_hosts - ssh user@server.example.com 'whoami'

Connection Refused

Cause: SSH service not running or firewall blocking

Solution:

  • Verify SSH service is running on target

  • Check firewall rules

  • Try specifying port: ssh -p 2222 user@server.example.com

Key Format Not Supported

Cause: Using newer key format not supported by older SSH

Solution: Generate key in PEM format

ssh-keygen -t rsa -b 4096 -m PEM -f pipelines_key

Best Practices

  • Use dedicated keys: Create separate SSH keys for pipelines, not personal keys

  • Rotate keys regularly: Update SSH keys periodically

  • Limit key permissions: Configure keys with minimum necessary permissions

  • Use secured variables: Store additional keys as secured variables

  • Add known hosts: Always verify host keys for security

  • Document key usage: Keep track of what each key accesses

  • Restrict server access: Only allow pipeline IPs if possible

  • Use SSH agent: For complex multi-key scenarios

  • Test locally: Verify SSH access works before adding to pipeline

  • Monitor access logs: Review server logs for unauthorized access

Security Considerations

  • Never commit private keys to your repository

  • Use secured variables for storing keys in Bitbucket

  • Rotate keys after team member departures

  • Audit key usage regularly

  • Use key passphrases when possible

  • Restrict key scope to specific commands if supported

  • Enable 2FA on target servers when available

  • Monitor failed login attempts on target servers

Next Steps

Still need help?

The Atlassian Community is here for you.