Using contexts :: CircleCI Documentation

5 min read Original article ↗

Restrict contexts by setting up expression restrictions. Expression restrictions are rules that pipeline values must match. Using expression restrictions allows you to create arbitrary constraints on the circumstances in which a context is available for use. For example, you may have a context containing credentials that should only be used for deploying your code from your protected main branch:

pipeline.git.branch == "main" and not job.ssh.enabled and not (pipeline.config_source starts-with "api"")

Tabs and new lines are considered whitespace so can be used to break long lines, but have no other significance. For example, the snippet above could also be written:

pipeline.git.branch == "main"
and not job.ssh.enabled
and not (pipeline.config_source starts-with "api")

You can set up expression restrictions using the context restriction API, or via the Context page () in the CircleCI web app.

Rules are expressed in a small language that supports equality checks, numeric comparisons, and boolean and, or, and not operators.

Set an expression restriction

You must be an organization administrator to set an expression restriction.

Follow these steps to set an expression restriction on a context:

  • CircleCI UI

  • API

  1. Navigate to the page of your organization in the CircleCI web app

  2. Select the context you want to add an expression restriction to

  3. Select Add Expression Restriction

  4. Enter your expression in the text box and select Add Expression Restriction again to confirm

Using server? If you are using CircleCI server, replace https://circleci.com with your server hostname when interacting with the CircleCI API.
  1. Set up your API authentication. Steps are available in the API developers guide.

  2. You are going to need your organization ID. In the CircleCI web app select Organization Settings in the sidebar and copy your "Organization ID" somewhere safe.

  3. To get the ID for your context, list your contexts, as follows, substituting your organization ID:

    curl --request GET \
      --url 'https://circleci.com/api/v2/context?owner-id=<your-org-ID>&page-token=NEXT_PAGE_TOKEN' \
      --header "Circle-Token: ${CIRCLE_TOKEN}" \
      --header "Accept: application/json" \
      --header "Content-Type: application/json" | jq
  4. Copy the ID for your context from the previous API response

  5. Create your context expression restriction, as follows, substituting your context ID and expression restriction:

    curl --request POST \
      --url https://circleci.com/api/v2/context/<your-context-ID>/restrictions \
      --header "Circle-Token: ${CIRCLE_TOKEN}" \
      --header 'content-type: application/json' \
      --data '{"restriction_type":"expression","restriction_value":"<your-expression-restriction>"}'

Examples

Allow the context only on the project’s main branch:

pipeline.git.branch == "main"

Allow the context only on the project’s main branch, or branches starting with integration-test:

pipeline.git.branch == "main" or pipeline.git.branch starts-with "integration-test"
pipeline.git.branch == "main" and not job.ssh.enabled and not (pipeline.config_source starts-with "api")

Variables

Pipeline values can be used as variables in an expression restriction. The exception to this is that pipeline.trigger_parameters.* pipeline values cannot be used. Pipeline parameters cannot be used in expression restrictions.

Job-specific variables are also available to use in expressions, as follows:

If an expression references a variable that has no value set in the pipeline, the expression will fail closed and prevent use of the context.

Errors

Any errors evaluating an expression will fail closed and prevent use of the context. Errors include the following:

  • Using a variable that does not exist

  • Using a non-numeric value as an operand to the numeric comparison operators

  • Using a non-string value as an operand to the starts-with operator

Operators

The operators you can use are described in the following table. You can also group sub-expressions with parentheses (, ). as in the example above.

Precedence

The following table shows operator precedence table, from weakest to strongest binding.

All operators are left associative. In practice, you should avoid operator chaining for anything other than and or or. This is because evaluation may cause type mismatches for other operators (see Evaluation).

Literals

Numbers

Numeric literals are whole integers (longs). For example, 1 or 768.

Strings

String literals are enclosed within double-quotes " ". The \ character is used to escape an embedded quote, or to escape an embedded \.

For example, "the quick brown fox", "You can embed \" and \\ characters"

Booleans

The boolean literals are true and false.

Evaluation

An expression is evaluated to produce a single boolean true or false value.

Other than the boolean value false, all values ultimately evaluate as true.

A variable evaluates to the variable’s value. If the variable does not exist then the expression is immediately considered to have evaluated as false. In other words, expression evaluation will fail closed when it encounters an unknown variable.

As an expression is evaluated, the result of an operator is effectively embedded "in place" as the evaluation continues. For example, to evaluate the following:

pipeline.git.branch == "main"
and not job.ssh.enabled
and not (pipeline.config_source starts-with "api")

where the values are:

  • pipeline.git.branch is "main"

  • job.ssh.enabled is false

  • pipeline.config_source is "api"

    1. Variable lookup: replace pipeline.git.branch with its value:

      1. "main" == "main" and not job.ssh.enabled and not (pipeline.config_source starts-with "api")

    2. Evaluate "main" == "main":

      1. true and not job.ssh.enabled and not (pipeline.config_source starts-with "api")

    3. Variable lookup: replace job.ssh.enabled with its value:

      1. true and not false and not (pipeline.config_source starts-with "api")

    4. Evaluate not false:

      1. true and true and not (pipeline.config_source starts-with "api")

    5. Evaluate true and true:

      1. true and not (pipeline.config_source starts-with "api")

    6. Variable lookup: replace pipeline.config_source with its value:

      1. true and not ("api" starts-with "api")

    7. Evaluate ("api" starts-with "api")

      1. true and not true

    8. Evaluate not true:

      1. true and false

    9. Evaluate true and false:

      1. false

    10. The result is false