Virtual environments for GitHub Actions

GitHub uses hosted virtual machines to run workflows. The virtual machine contains an environment of tools, packages, and settings available for GitHub Actions to use.

GitHub Actions is currently in limited public beta and is subject to change. We strongly recommend that you do not use this feature for high-value workflows and content during the beta period. For more information about the beta, see "About GitHub Actions."

For more information about using GitHub Actions, see "Automating your workflow with GitHub Actions."

In this article

About virtual environments

The Linux and Windows GitHub Actions virtual environments are hosted on Standard_DS2_v2 virtual machines in Microsoft Azure with the GitHub Actions runner installed. The GitHub Actions runner is a fork of the Azure Pipelines Agent. For more information about the Standard_DS2_v2 machine resources, see "DSv2-series" in the Microsoft Azure documentation. GitHub uses MacStadium to host the macOS virtual environments.

When you use a GitHub-hosted machine, machine maintenance and upgrades are taken care of for you. You can run workflows directly on the virtual machine or in a Docker container.

The Linux and macOS virtual machines both run using passwordless sudo. When you need to execute commands or install tools that require more privileges than the current user, you can use sudo without needing to provide a password. For more information, see the "Sudo Manual." Windows virtual machines are configured to run as administrators with User Account Control (UAC) disabled. For more information, see "How User Account Control works."

GitHub hosts virtual machines with Linux, macOS, and Windows environments. Each job in a workflow executes in a fresh instance of the virtual environment. All steps in the job execute in the same instance of the virtual environment, allowing the actions in that job to share information using the filesystem.

You can specify the virtual environment for each job in a workflow. You can configure each job to run in different virtual environments or run all jobs in the same environment.

Supported virtual environments and hardware resources

Each virtual machine has the same hardware resources available.

GitHub provides more than one virtual environment. For a list of supported software, tools, and packages in each virtual environment, see "Software in virtual environments for GitHub Actions."

Virtual environment YAML workflow label
Windows Server 2019 windows-latest or windows-2019
Windows Server 2016 R2 windows-2016
Ubuntu 18.04 ubuntu-latest or ubuntu-18.04
Ubuntu 16.04 ubuntu-16.04
macOS X Mojave 10.14 macOS-latest or macOS-10.14

IP addresses of runners on GitHub-hosted machines

Windows and Ubuntu hosted runners are hosted in Azure and have the same IP address ranges as Azure Data centers. Currently, all hosted runners are in the East US 2 Azure region, but more regions may added over time.

Microsoft updates the Azure IP address ranges weekly in a JSON file that you can download from the Azure IP Ranges and Service Tags - Public Cloud website. You can use this range of IP addresses if you require an allow-list to prevent unauthorized access to your internal resources.

The JSON file contains an array called values. Inside that array, you can find the supported IP addresses in an object with a name and id of "AzureCloud.eastus2".

You can find the supported IP address ranges in the "addressPrefixes" object. This is a condensed example of the JSON file.

  "changeNumber": 84,
  "cloud": "Public",
  "values": [
      "name": "AzureCloud.eastus2",
      "id": "AzureCloud.eastus2",
      "properties": {
        "changeNumber": 33,
        "region": "eastus2",
        "platform": "Azure",
        "systemService": "",
        "addressPrefixes": [

Filesystems on GitHub-hosted machines

GitHub creates directories for actions to use. Actions that run in Docker containers have static directories under the /github path. The GitHub-specific paths on virtual machines that run JavaScript and shell script actions are not static. GitHub provides environment variables that you can use to construct file paths for the home, workspace, and workflow directories used by GitHub Actions. For a list of the environment variables GitHub creates for each action, see "Default environment variables."

Docker container filesystem

We strongly recommend using the default environment variables to construct file paths in Docker containers.

GitHub reserves the /github path prefix and creates three directories for actions.

Environment variables

GitHub sets default environment variables available to every step in a workflow run. Additional environment variables are set in the workflow file. An action can create, read, and modify environment variables.

You can define environment variables for a step in a workflow file using the jobs.<job_id>.steps.env keyword. The case for the environment variable name is preserved. For more information, see "Workflow syntax for GitHub."

  - name: Hello world
    run: echo Hello world $FIRST_NAME $middle_name $Last_Name!
      FIRST_NAME: Mona
      middle_name: The
      Last_Name: Octocat

Default environment variables

We strongly recommend that actions use environment variables to access the filesystem rather than hardcoded file paths. GitHub sets environment variables for actions to use in all virtual environments.

Environment variable Description
HOME The path to the GitHub home directory used to store user data. For example, /github/home.
GITHUB_WORKFLOW The name of the workflow.
GITHUB_ACTION The unique identifier (id) of the action.
GITHUB_ACTOR The name of the person or app that initiated the workflow. For example, octocat.
GITHUB_REPOSITORY The owner and repository name. For example, octocat/Hello-World.
GITHUB_EVENT_NAME The name of the webhook event that triggered the workflow.
GITHUB_EVENT_PATH The path of the file with the complete webhook event payload. For example, /github/workflow/event.json.
GITHUB_WORKSPACE The GitHub workspace directory path. The workspace directory contains a subdirectory with a copy of your repository if your workflow uses the actions/checkout action. If you don't use the actions/checkout action, the directory will be empty. For example, /home/runner/work/my-repo-name/my-repo-name.
GITHUB_SHA The commit SHA that triggered the workflow. For example, ffac537e6cbbf934b08745a378932722df287a53.
GITHUB_REF The branch or tag ref that triggered the workflow. For example, refs/heads/feature-branch-1. If neither a branch or tag is available for the event type, the variable will not exist.
GITHUB_HEAD_REF Only set for forked repositories. The branch of the head repository.
GITHUB_BASE_REF Only set for forked repositories. The branch of the base repository.

Naming conventions

Note: GitHub reserves the GITHUB_ environment variable prefix for internal use by GitHub. Setting an environment variable or secret with the GITHUB_ prefix will result in an error.

Any new environment variables you set that point to a location on the filesystem should have a _PATH suffix. The HOME and GITHUB_WORKSPACE default variables are exceptions to this convention because the words "home" and "workspace" already imply a location.

Creating and using secrets (encrypted variables)

Anyone with write access to a repository can read and use secrets.

Secrets are encrypted environment variables created in a repository and can only be used by GitHub Actions. GitHub encrypts secrets in the web browser using public-key authenticated encryption and the Poly1305 cipher algorithm. For more information, see the "TweetNaCl.js" documentation. To make a secret available to an action, you must set the secret as an input or environment variable in the workflow file.

GitHub automatically redacts secrets printed to the log, but you should avoid printing secrets to the log intentionally.

Secret names cannot include any spaces. To ensure that GitHub redacts your secret in logs, avoid using structured data as the values of secrets, like JSON or encoded Git blobs.

  1. On GitHub, navigate to the main page of the repository.

  2. Under your repository name, click Settings.

    Repository settings button

  3. In the left sidebar, click Secrets.

  4. Type a name for your secret in the "Name" input box.

  5. Type the value for your secret.

  6. Click Add secret.

To pass a secret to an action, set the secret as an input or environment variable in your workflow. Review the action's README file to learn about which inputs and environment variables the action expects. For more information, see "Workflow syntax for GitHub Actions."

With the exception of GITHUB_TOKEN, secrets are not passed to the runner when a workflow is triggered from a forked repository.

  - name: Hello world action
    with: # Set the secret as an input
      super_secret: ${{ secrets.SuperSecret }}
    env: # Or as an environment variable
      super_secret: ${{ secrets.SuperSecret }}


GitHub automatically creates a GITHUB_TOKEN secret to use in your workflow.

When you enable GitHub Actions, GitHub installs a GitHub App on your repository. The GITHUB_TOKEN secret is a GitHub App installation access token used to authenticate on behalf of the GitHub App installed on your repository. The token's permissions are limited to the repository that contains your workflow. For more information, see "Token permissions."

To use the GITHUB_TOKEN secret, you must add it to your workflow file. Using a token might include passing the token as an input to an action that requires it, or making authenticated GitHub API calls.

If you need a token that requires permissions that aren't available in the GITHUB_TOKEN, you can create a personal access token and set it as a secret in your repository:

  1. Use or create a token with the appropriate permissions for that repository. For more information, see "Creating a personal access token for the command line."
  2. Add the token as a secret in your workflow's repository, and refer to it using the ${{ secrets.SECRET_NAME }} syntax. For more information, see "Creating and using secrets (encrypted variables)."
Token permissions

For information about the API endpoints GitHub Apps can access with each permission, see "GitHub App Permissions" in the GitHub Developer documentation.

Permission Access type Access by forked repos
checks read/write read
contents read/write read
deployments read/write read
issues read/write read
metadata read read

Note: Docker and Ruby Gem packages are not currently supported.
read/write read
pull requests read/write read
repository projects read/write read
statuses read/write read

Limits for secrets

Your workflow can have up to 100 secrets, and the names of secret environment variables must be unique per repository.

Secrets are limited to 64 KB in size. To use secrets that are larger than 64 KB, you can store encrypted secrets in your repository and save the decryption passphrase as a secret on GitHub. For example, you can use gpg to encrypt your credentials locally before checking the file in to your repository on GitHub. For more information, see the "gpg manpage."

Warning: Be careful that your secrets do not get printed when your action runs. When using this workaround, GitHub does not redact secrets that are printed in logs.

  1. Run the following command from your terminal to encrypt the my_secret.json file using gpg and the AES256 cipher algorithm.

    $ gpg --symmetric --cipher-algo AES256 my_secret.json
  2. You will be prompted to enter a passphrase. Remember the passphrase, because you'll need to create a new secret on GitHub that uses the passphrase as the value.

  3. Create a new secret in your repository to store the passphrase. For example, create a new secret with the name LARGE_SECRET_PASSPHRASE and set the value of the secret to the passphrase you selected in the step above.

  4. Copy your encrypted file into your repository and commit it. In this example, the encrypted file is my_secret.json.gpg.

  5. Create a shell script to decrypt the password. Save this file as

    # Decrypt the file
    mkdir $HOME/secrets
    # --batch to prevent interactive command --yes to assume "yes" for questions
    gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" \
    --output $HOME/secrets/my_secret.json my_secret.json.gpg
  6. Ensure your shell script is executable before checking it in to your repository.

    $ chmod +x
    $ git add
    $ git commit -m "Add new decryption script"
    $ git push
  7. From your workflow, use a step to call the shell script and decrypt the secret. To have a copy of your repository in the virtual environment that your workflow runs in, you'll need to use the actions/checkout action. Reference your shell script using the run command relative to the root of your repository.

    name: Workflows with large secrets
    on: push
        name: My Job
        runs-on: ubuntu-latest
          - uses: actions/checkout@v1
          - name: Decrypt large secret
            run: ./.github/scripts/
          # This command is just an example to show your secret being printed
          # Ensure you remove any print statements of your secrets. GitHub does
          # not hide secrets that use this workaround.
          - name: Test printing your secret (Remove this step in production)
            run: cat $HOME/secrets/my_secret.json

Ask a human

Can't find what you're looking for?

Contact us