---
title: "Manage contexts with config policies"
description: "Write config policies that control context use in your organization by defining which contexts are allowed, blocked, or reserved by a project or branch."
platform: "Cloud, Server"
doc_version: "Server"
last_updated: "2026-10-07"
---

> For current CircleCI product defaults, deprecated patterns, and Cloud/Server differences, see [AGENTS.md](https://circleci.com/docs/AGENTS.md).
>
> For the complete documentation index and site structure, see [llms.txt](https://circleci.com/docs/llms.txt).

# Manage contexts with config policies

Follow this how-to guide to create config policies for managing the use of contexts in your organization. For more information about config policies, see the [Config Policies Overview](https://circleci.com/docs/guides/server/config-policies/config-policy-management-overview/).

When using the `circleci policy` commands, use the `policy-base-url` flag to provide your CircleCI Server domain. For example:

```shell
circleci policy push ./config-policies --owner-id <your-organization-ID> --policy-base-url <your-circleci-server-domain>
```

## Introduction

Config policies use a decision engine based on OPA ([Open Policy Agent](https://www.openpolicyagent.org/)). The engine returns a decision about whether a pipeline’s config complies with your policies. In the strictest case, a non-compliant pipeline configuration will be blocked from triggering until it complies.

Well-designed secrets management is a delicate balancing act between security and usability. To help with this balance, you can lock down contexts at different levels using config policies.

This guide presents a selection of _helpers_ (CircleCI-specific Rego functions) useful for writing context policies in your organization.

The contexts helpers covered are as follows:

*   [`contexts_allowed_by_project_ids`](https://circleci.com/docs/reference/config-policy-reference/#contexts-allowed-by-project-ids)
    
*   [`contexts_blocked_by_project_ids`](https://circleci.com/docs/reference/config-policy-reference/#contexts-blocked-by-project-ids)
    
*   [`contexts_reserved_by_project_ids`](https://circleci.com/docs/reference/config-policy-reference/#contexts-reserved-by-project-ids)
    
*   [`contexts_reserved_by_branches`](https://circleci.com/docs/reference/config-policy-reference/#contexts-reserved-by-branches)
    

In the examples on this page, project IDs, branch names, and context names can be supplied using the following types:

*   String
    
*   Set of strings
    
*   Array of strings
    

## Prerequisites

*   A CircleCI Account connected to a supported VCS.
    
*   Install/update the CircleCI CLI, and ensure you have authenticated with a token before attempting to use the CLI with config policies. See the [Installing the Local CLI](https://circleci.com/docs/guides/server/toolkit/circleci-cli/) page for more information.
    
*   Ensure you have **enabled** config policy evaluation for your organization so that project configurations **will** be evaluated against your organization’s policies when pipelines are triggered:
    
    ```shell
    circleci policy settings --enabled=true --owner-id <your-organization-ID>
    ```
    
    Example output:
    
    ```shell
    {
      "enabled": true
    }
    ```
    
    To find your organization ID and organization slug, select **Org** in the CircleCI web app sidebar to open your organization settings page.
    
    The organization ID is available to copy from the org settings overview page.
    
    > **Image:** screenshot showing where to find your organization ID
    
    Figure 1. Organization ID available in organization settings
    
*   It is recommended to run through the [Create a Policy](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#create-a-policy) and [Manage Policies With Your VCS](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs) guides first. Best practice is to use a repository within your organization to store and develop your policies. The [Manage Policies With Your VCS](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs) guide walks through setting this up and setting up a pipeline for policy development.
    
*   To use the examples set out on this page, you will need to be using contexts to store secrets. For more information, see the [Using Contexts](https://circleci.com/docs/guides/server/security/contexts/) page.
    

## Define the contexts allowed for a project

You may want to allow specific projects the use of only certain contexts. For example, you might want to only allow contexts that have EKS-related deployment keys to projects architected to be deployed on EKS using those keys.

To achieve this, use the [`contexts_allowed_by_project_ids`](https://circleci.com/docs/reference/config-policy-reference/#contexts-allowed-by-project-ids) helper to create a policy to apply this restriction. This helper function accepts project IDs and context names, and prevents the usage of contexts that are **not** in the allow-list for all specified projects.

### 1\. Create your policy

1.  If you have not already done so, create an empty directory to store your policies. For example:
    
    ```shell
    mkdir ./config-policies
    ```
    
2.  Create a new file in this directory for your new policy. Name the file `allow_contexts.rego`.
    
3.  Copy the following snippet into the `allow_contexts.rego` file you just made:
    
    ```go
    # All policies start with the org package definition
    package org
    
    # import CircleCI specific helper functions
    import data.circleci.config
    
    # Declare a policy name
    policy_name["contexts_allowed_by_project"]
    
    # Declare a rule
    rule_contexts_allowed_by_project_ids = config.contexts_allowed_by_project_ids(
        ["<project-ID>"],
        ["<context-1>","<context-2>"]
    )
    
    # Enable the rule and choose the hard_fail enforcement level
    enable_hard["rule_contexts_allowed_by_project_ids"]
    ```
    
    Notice the `contexts_allowed_by_project_ids` helper is accessed using the `config` keyword.
    
    In the following steps you will replace `<project-ID>` and `<context-1>` (and `<context-2>` if you choose to use more than one) with _your_ projects and contexts. The `allow_contexts.rego` policy, once uploaded, will restrict your specified project to only have access to the context(s) in your allow-list.
    

### 2\. Update policy with your details

1.  Replace `<project-ID>` with the ID for the project you want to restrict:
    
    *   In the CircleCI web app, select **Projects** from the sidebar, and click the ellipsis (`…​`) next to your project, and select **Project Settings** to locate the Project ID.
        
    
2.  Replace `<context-1>` with the name of the context you want to allow the use of. You can add multiple contexts as an array, or stick with one for now.
    
    *   To find a list of your contexts, select **Organization settings** from the sidebar in the CircleCI web app and then select **Contexts** from the menu.
        
    

### 3\. Push up your policy bundle

You can now push your new policy to your organization for it to take effect. You have two options:

*   Push the policy manually using the CLI from your local environment.
    
*   Push your changes to your config policy repository if you are managing policies via your VCS as shown in the [Manage Policies With Your VCS Guide](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs).
    

<Tabs>
<Tab title="Manual">

Create and upload the policy bundle using CircleCI CLI:

```shell
circleci policy push ./config-policies --owner-id <your-organization-ID>
```

If the upload was successful, you will see something like the following:

```shell
{
  “Created”: [“contexts_allowed_by_sample_project”]
}
```

</Tab>
<Tab title="Push to VCS">

Set up your config policies repository using the sample configuration in the [Manage Policies With Your VCS Guide](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs). Push your changes to the `main` branch of your config policies repository. The CircleCI web app will then show your policy pipeline running.

You can also push to a development branch. Doing this gives you a diff of your policy bundle rather than pushing the new policy to your CircleCI organization. Pushing to a development branch is useful during policy development.

</Tab>
</Tabs>

If you would like to write tests for your policy, check out the [Test Config Policies](https://circleci.com/docs/guides/server/config-policies/test-config-policies/) guide.

### Conclusion

Once you have pushed your new `allow_contexts.rego` policy, any pipeline trigger for the specified project that accesses blocked contexts will fail. Developers will be notified on the dashboard as shown below.

> **Image:** Dashboard page

Figure 2. Dashboard showing context policy failure

### Use sets and variables

In this example, you have hard coded your project IDs and context names into your policy. Hard-coded IDs make policies hard to read and understand. A better way is to [Use Sets and Variables](https://circleci.com/docs/guides/server/config-policies/config-policy-management-overview/#use-sets-and-variables) defined in separate `.rego` files. To use this method, follow these steps:

1.  Create three files for your contexts and IDs: `project_ids.rego`, `project_groups.rego` and `context_groups.rego` so you end up with the following file structure:
    
    ```shell
    ├── config-policies/
    │   ├── allow_contexts.rego
    │   ├── project_ids.rego
    │   ├── project_groups.rego
    │   ├── context_groups.rego
    ```
    
2.  Add the following to your new `.rego` files, and replace IDs and context names shown between `< >` with your data as shown in the previous section:
    
    *   `project_id.rego`
        
        ```go
        # Single application project IDs. Can be automated.
        my_project_id := “<project-ID>”
        ```
        
    *   `project_groups.rego`
        
        ```go
        # sets can be used to group variables
        Front_end_applications := {my_project_id}
        ```
        
    *   `context_groups.rego`
        
        ```go
        # sets can be used to group variables
        Front_end_application_contexts := {"<context-1>","<context-2>"}
        ```
        
    
3.  You can now rewrite your `allow_policy.rego` policy as follows:
    
    ```go
    # All policies start with the org package definition
    package org
    
    # import CircleCI specific helper functions
    import data.circleci.config
    
    # Declare a policy name
    policy_name["contexts_allowed_by_sample_project"]
    
    # Declare a rule
    rule_contexts_allowed_by_project_ids = config.contexts_allowed_by_project_ids(
        Front_end_applications,
        Front_end_application_contexts
    )
    
    # Enable the rule and choose the hard_fail enforcement level
    enable_hard["rule_contexts_allowed_by_project_ids"]
    ```
    

## Define the contexts blocked for a project

To add an extra layer of security to secrets management, block access to certain contexts for projects that must not access those secrets for security or compliance reasons.

Use the `contexts_blocked_by_project_ids` helper to create a policy to apply this restriction. This helper function accepts project IDs and context names, and prevents the usage of any contexts in the block-list for all specified projects.

### 1\. Create your policy

1.  If you have not already done so, create an empty directory to store your policies. For example:
    
    ```shell
    mkdir ./config-policies
    ```
    
2.  Create a new file in this directory for your new policy. Name the file `block_contexts.rego`.
    
3.  Copy the following snippet into the `block_contexts.rego` file you just made:
    
    ```go
    # All policies start with the org package definition
    package org
    
    # import CircleCI specific helper functions
    import data.circleci.config
    
    # Declare a policy name
    policy_name["contexts_blocked_by_sample_project"]
    
    # Declare a rule
    rule_contexts_blocked_by_project_ids = config.contexts_blocked_by_project_ids(
        ["<project-ID>"],
        ["<context-1>","<context-2>"]
    )
    
    # Enable the rule and choose the hard_fail enforcement level
    enable_hard["rule_contexts_blocked_by_project_ids"]
    ```
    
    Notice the `contexts_blocked_by_project_ids` helper is accessed using the `config` keyword.
    
    In the following steps you will replace `<project-ID>` and `<context-1>` (and `<context-2>` if you choose to use more than one) with _your_ projects and contexts. The `block_contexts.rego` policy, once uploaded, will restrict your specified project so that it will not have access to the context(s) in your block-list.
    

### 2\. Update policy with your details

1.  Replace `<project-ID>` with the ID for the project you want to restrict:
    
    *   In the CircleCI web app, select **Projects** from the sidebar, and click the ellipsis (`…​`) next to your project. Select **Project Settings** to locate the Project ID.
        
    
2.  Replace `<context-1>` with the name of the context you want to block the use of. You can add multiple contexts as an array, or stick with one for now.
    
    *   To find a list of your contexts, select **Organization settings** from the sidebar in the CircleCI web app and then select **Contexts** from the menu.
        
    

### 3\. Push up your policy bundle

You can now push your new policy to your organization for it to take effect. You have two options:

*   Push the policy manually using the CLI from your local environment.
    
*   Push your changes to your config policy repository if you are managing policies via your VCS as shown in the [Manage Policies With Your VCS Guide](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs).
    

<Tabs>
<Tab title="Manual">

Create and upload the policy bundle using CircleCI CLI:

```shell
circleci policy push ./config-policies --owner-id <your-organization-ID>
```

If the upload was successful, you will see something like the following:

```shell
{
  “Created”: [“contexts_blocked_by_sample_project”]
}
```

</Tab>
<Tab title="Push to VCS">

Set up your config policies repository using the sample configuration in the [Manage Policies With Your VCS Guide](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs). Push your changes to the `main` branch of your config policies repository. The CircleCI web app will then show your policy pipeline running.

You can also push to a development branch. Doing this gives you a diff of your policy bundle rather than pushing the new policy to your CircleCI organization. Pushing to a development branch is useful during policy development.

</Tab>
</Tabs>

If you would like to write tests for your policy, check out the [Test Config Policies](https://circleci.com/docs/guides/server/config-policies/test-config-policies/) guide.

### Conclusion

Once you have pushed your new `block_contexts.rego` policy, any pipeline trigger for the specified project that accesses blocked contexts will fail. Developers will be notified on the dashboard as shown below.

> **Image:** Dashboard page showing fail

Figure 3. Dashboard showing context block policy failure

## Define the contexts reserved by a project

You may want to reserve contexts for use by a defined list of projects, blocking the use of those contexts by any project not in the allow-list. One possible use case for this would be locking contexts containing deployment keys to only those applications (projects) that need it. Any app that does not need this access will not be able to access those contexts. Developers will receive a hard fail, and pipelines will fail to trigger.

Use the `contexts_reserved_by_project_ids` helper to create a policy to apply this restriction. This helper function accepts project IDs and context names. It prevents the usage of any reserved contexts for projects that are not in the allow-list.

### 1\. Create your policy

1.  If you have not already done so, create an empty directory to store your policies. For example:
    
    ```shell
    mkdir ./config-policies
    ```
    
2.  Create a new file in this directory for your new policy. Name the file `reserve_contexts.rego`.
    
3.  Copy the following snippet into the `reserve_contexts.rego` file you just made:
    
    ```go
    # All policies start with the org package definition
    package org
    
    # import CircleCI specific helper functions
    import data.circleci.config
    
    # Declare a policy name
    policy_name["reserved_contexts"]
    
    # Declare a rule
    rule_reserve_contexts = config.contexts_reserved_by_project_ids(
        ["<project-ID-1>","<project-ID-2>"],
        ["<context-1>","<context-2>"]
    )
    
    # Enable the rule and choose the hard_fail enforcement level
    enable_hard["rule_reserve_contexts"]
    ```
    
    Notice the `contexts_reserved_by_project_ids` helper is accessed using the `config` keyword.
    
    In the following steps you will replace `<project-ID-1>` and `<context-1>` (and `<project-ID-2>` and `<context-2>` if you choose to use more than one) with _your_ projects and contexts. The `reserve_contexts.rego` policy, once uploaded, will restrict your specified context(s) so that they can only be used by the project(s) you have added to the allow-list.
    

### 2\. Update policy with your details

1.  Replace `<project-ID-1>` with the ID for the first project you want to add to the allow-list. You can add multiple project IDs as an array, or stick with one for now:
    
    *   In the CircleCI web app, select **Projects** from the sidebar, and click the ellipsis (`…​`) next to your project, and select **Project Settings** to locate the Project ID.
        
    
2.  Replace `<context-1>` with the name of the first context you want to restrict the use of. You can add multiple contexts as an array, or stick with one for now.
    
    *   To find a list of your contexts, select **Organization settings** from the sidebar in the CircleCI web app and then select **Contexts** from the menu.
        
    

### 3\. Push up your policy bundle

You can now push your new policy to your organization for it to take effect. You have two options:

*   Push the policy manually using the CLI from your local environment.
    
*   Push your changes to your config policy repository if you are managing policies via your VCS as shown in the [Manage Policies With Your VCS Guide](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs).
    

<Tabs>
<Tab title="Manual">

Create and upload the policy bundle using CircleCI CLI:

```shell
circleci policy push ./config-policies --owner-id <your-organization-ID>
```

If the upload was successful, you will see something like the following:

```shell
{
  “Created”: [“reserved_contexts”]
}
```

</Tab>
<Tab title="Push to VCS">

Set up your config policies repository using the sample configuration in the [Manage Policies With Your VCS Guide](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs). Push your changes to the `main` branch of your config policies repository. The CircleCI web app will then show your policy pipeline running.

You can also push to a development branch. Doing this gives you a diff of your policy bundle rather than pushing the new policy to your CircleCI organization. Pushing to a development branch is useful during policy development.

</Tab>
</Tabs>

If you would like to write tests for your policy, check out the [Test Config Policies](https://circleci.com/docs/guides/server/config-policies/test-config-policies/) guide.

### Conclusion

Once you have pushed your new `reserve_contexts.rego` policy, any pipeline trigger for a project outside your allow-list that attempts to access reserved contexts will fail. Developers will be notified on the dashboard as shown below.

## Define the contexts reserved by a branch

You may want to restrict which contexts (and therefore secrets) are available depending on which branch is being built. Using branch-based restrictions, you can manage your application environment in one repository, and lock down the use of secrets to individual branches. For example, you could split up production secrets and development secrets. This allows you to ensure that production secrets cannot be accessed by a build on a development branch.

Use the [`contexts_reserved_by_branches`](https://circleci.com/docs/reference/config-policy-reference/#contexts-reserved-by-branches) helper to define a policy for this use case. This helper function accepts branch names and context names. Only pipelines running on specified branches are allowed access to contexts in the allow-list.

### 1\. Create your policy

1.  If you have not already done so, create an empty directory to store your policies. For example:
    
    ```shell
    mkdir ./config-policies
    ```
    
2.  Create a new file in this directory for your new policy. Name the file `context_protection.rego`.
    
3.  Copy the following snippet into the `context_protection.rego` file you just made:
    
    ```go
    # All policies start with the org package definition
    package org
    
    # import CircleCI specific helper functions
    import data.circleci.config
    
    # Declare a policy name
    policy_name["prod_context_protection"]
    
    # Declare a rule
    use_prod_context_on_main = config.contexts_reserved_by_branches(["main"],
        ["<context-1>","<context-2>"]
    )
    
    # This rule will apply to all projects subscribed in project_groups.rego under policy_restrict_context_access
    enable_rule["use_prod_context_on_main"]{
        policy_restrict_context_access[data.meta.project_id]
    }
    hard_fail["use_prod_context_on_main"]
    ```
    
    Notice the `contexts_reserved_by_branches` helper is accessed using the `config` keyword.
    
4.  Create a second Rego file named `project_groups.rego` to specify an additional restriction on which projects are affected by this rule. Replace `<project-ID>` with one of your project IDs.
    
    `project_groups.rego`
    
    ```go
    # sets can be used to group variables
    policy_restrict_context_access := <project-ID>
    ```
    

In the following steps you will replace `<context-1>` (and `<context-2>` if you choose to use more than one) with _your_ context name. The `context_protection.rego` policy, once uploaded, will restrict use of your specified context(s) to builds on the `main` branch, for projects specified in `project_groups.rego`.

### 2\. Update policy with your details

1.  Replace `<context-1>` with the name of the context you want to allow the use of. You can add multiple contexts as an array, or stick with one for now.
    
    *   To find a list of your contexts, select **Organization settings** from the sidebar in the CircleCI web app and then select **Contexts** from the menu.
        
    

### 3\. Push up your policy bundle

You can now push your new policy to your organization for it to take effect. You have two options:

*   Push the policy manually using the CLI from your local environment.
    
*   Push your changes to your config policy repository if you are managing policies via your VCS as shown in the [Manage Policies With Your VCS Guide](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs).
    

<Tabs>
<Tab title="Manual">

Create and upload the policy bundle using CircleCI CLI:

```shell
circleci policy push ./config-policies --owner-id <your-organization-ID>
```

If the upload was successful, you will see something like the following:

```shell
{
  “Created”: [“prod_context_protection”]
}
```

</Tab>
<Tab title="Push to VCS">

Set up your config policies repository using the sample configuration in the [Manage Policies With Your VCS Guide](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/#manage-policies-with-your-vcs). Push your changes to the `main` branch of your config policies repository. The CircleCI web app will then show your policy pipeline running.

You can also push to a development branch. Doing this gives you a diff of your policy bundle rather than pushing the new policy to your CircleCI organization. Pushing to a development branch is useful during policy development.

</Tab>
</Tabs>

If you would like to write tests for your policy, check out the [Test Config Policies](https://circleci.com/docs/guides/server/config-policies/test-config-policies/) guide.

### Conclusion

Once you have pushed your new `context_protection.rego` policy, any pipeline triggered on a branch other than `main` that uses production contexts will fail. Developers will also be notified on the dashboard.

## Next steps

*   [Create and Manage Config Policies](https://circleci.com/docs/guides/server/config-policies/create-and-manage-config-policies/)
    
*   [Test Config Policies](https://circleci.com/docs/guides/server/config-policies/test-config-policies/)
    
*   [Config Policy Reference](https://circleci.com/docs/reference/config-policy-reference/)