CircleCI Field Guide
GitHub Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

Restricting A Full Config File

Full Config File Restriction

This is a policy that enforces a rule on the following config file as a whole. This method may be more effective for smaller, static config files. i.e A setup config

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package org

policy_name["project_lock"]

# A locks the policy to a specific project via UUID
# UUID can be found in the CircleCI UI under Project Settings > Overview
# use care to avoid naming collisions as assignments are global across the entire policy bundle
project_id := "your-project-UUID"

# enables the rule only for the setup workflow
enable_hard["check_project_config"] { input.setup == true }

check_project_config[reason] {
  # Feed full setup.yml contents into expected
  expected := yaml.unmarshal(`
  version: 2.1

  setup: true

  orbs:
    continuation: circleci/continuation@0.2.0

  jobs:
    setup:
      docker: 
        - image: cimg/node:19.7.0
      resource_class: small
      steps:
        - checkout
        - run: node .circleci/generated/generated.index.js
        - continuation/continue:
            configuration_path: basic_workflow.yml

  workflows:
    setup-workflow:
      jobs:
        - setup
  `)

    # the _compiled_ key exists along side the other keys of the uncompiled config
    # so, the data will never match.
    # we can remove the compiled value at which point, we should be comparing the
    # unmarshaled expected value against the input map.
    uncompiled_input := object.remove(
        input,
        {"_compiled_"}, # remove the compiled key from the input
    )

  # uncompiled_input is the original input, with the compiled key removed
  uncompiled_input != expected
  # Prints the expected config in the UI to assist with correctig the policy violation
  reason := sprintf("config.yml cannot be changed\n\nFound:\n%s\n\nExpected:\n%s", [uncompiled_input, expected])

Example Config File

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
version: 2.1

setup: true

orbs:
  continuation: circleci/continuation@0.2.0
  node: circleci/node@5.1.0

jobs:
  setup:
    docker: 
      - image: cimg/node:19.7.0
    resource_class: small
    steps:
      - checkout
      - node/install-packages:
          app-dir: .circleci/generated
      - run: node .circleci/generated/generated.index.js
      - continuation/continue:
          configuration_path: basic_workflow.yml

workflows:
  setup-workflow:
    jobs:
      - setup

Common Use Cases

  • Restricting a setup config to enforce triggers, use a centralized config system
  • Restricting a dependency project with a static config files

Documentation